|
Boost-Commit : |
From: bdawes_at_[hidden]
Date: 2008-07-15 09:53:49
Author: bemandawes
Date: 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
New Revision: 47443
URL: http://svn.boost.org/trac/boost/changeset/47443
Log:
Merge trunk
Added:
branches/release/tools/build/v2/contrib/
- copied from r47441, /trunk/tools/build/v2/contrib/
branches/release/tools/build/v2/contrib/boost.jam
- copied unchanged from r47441, /trunk/tools/build/v2/contrib/boost.jam
branches/release/tools/build/v2/contrib/tntnet.jam
- copied unchanged from r47441, /trunk/tools/build/v2/contrib/tntnet.jam
branches/release/tools/build/v2/test/file_name_handling.py
- copied unchanged from r47441, /trunk/tools/build/v2/test/file_name_handling.py
branches/release/tools/build/v2/test/qt4/
- copied from r47441, /trunk/tools/build/v2/test/qt4/
branches/release/tools/build/v2/test/qt4.py
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4.py
branches/release/tools/build/v2/test/qt4/Jamroot
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/Jamroot
branches/release/tools/build/v2/test/qt4/phonon.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/phonon.cpp
branches/release/tools/build/v2/test/qt4/qt3support.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qt3support.cpp
branches/release/tools/build/v2/test/qt4/qtassistant.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtassistant.cpp
branches/release/tools/build/v2/test/qt4/qtcore.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtcore.cpp
branches/release/tools/build/v2/test/qt4/qtcorefail.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtcorefail.cpp
branches/release/tools/build/v2/test/qt4/qtgui.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtgui.cpp
branches/release/tools/build/v2/test/qt4/qthelp.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qthelp.cpp
branches/release/tools/build/v2/test/qt4/qtnetwork.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtnetwork.cpp
branches/release/tools/build/v2/test/qt4/qtscript.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtscript.cpp
branches/release/tools/build/v2/test/qt4/qtsql.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtsql.cpp
branches/release/tools/build/v2/test/qt4/qtsvg.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtsvg.cpp
branches/release/tools/build/v2/test/qt4/qttest.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qttest.cpp
branches/release/tools/build/v2/test/qt4/qtwebkit.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtwebkit.cpp
branches/release/tools/build/v2/test/qt4/qtxml.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtxml.cpp
branches/release/tools/build/v2/test/qt4/qtxmlpatterns.cpp
- copied unchanged from r47441, /trunk/tools/build/v2/test/qt4/qtxmlpatterns.cpp
branches/release/tools/build/v2/test/sort_rule.py
- copied unchanged from r47441, /trunk/tools/build/v2/test/sort_rule.py
branches/release/tools/build/v2/tools/types/objc.jam
- copied unchanged from r47441, /trunk/tools/build/v2/tools/types/objc.jam
Properties modified:
branches/release/tools/build/v2/debian/boost-build.docs (props changed)
branches/release/tools/build/v2/debian/boost-build.examples (props changed)
branches/release/tools/build/v2/debian/changelog (props changed)
branches/release/tools/build/v2/debian/conffiles (props changed)
branches/release/tools/build/v2/debian/control (props changed)
branches/release/tools/build/v2/debian/copyright (props changed)
branches/release/tools/build/v2/debian/excludes (props changed)
branches/release/tools/build/v2/debian/rules (props changed)
branches/release/tools/build/v2/example/customization/class.verbatim (props changed)
branches/release/tools/build/v2/example/customization/t1.verbatim (props changed)
branches/release/tools/build/v2/example/customization/t2.verbatim (props changed)
branches/release/tools/build/v2/example/customization/usage.verbatim (props changed)
branches/release/tools/build/v2/example/generate/Jamroot (props changed)
branches/release/tools/build/v2/example/generator/Jamroot (props changed)
branches/release/tools/build/v2/example/generator/foo.gci (props changed)
branches/release/tools/build/v2/example/gettext/russian.po (props changed)
branches/release/tools/build/v2/example/hello/Jamroot (props changed)
branches/release/tools/build/v2/example/libraries/Jamroot (props changed)
branches/release/tools/build/v2/example/make/Jamroot (props changed)
branches/release/tools/build/v2/example/make/main_cpp.pro (props changed)
branches/release/tools/build/v2/example/pch/Jamroot (props changed)
branches/release/tools/build/v2/example/python_modules/Jamroot (props changed)
branches/release/tools/build/v2/example/qt/qt3/hello/Jamroot (props changed)
branches/release/tools/build/v2/example/qt/qt3/moccable-cpp/Jamroot (props changed)
branches/release/tools/build/v2/example/qt/qt3/uic/Jamroot (props changed)
branches/release/tools/build/v2/example/qt/qt3/uic/hello_world_widget.ui (props changed)
branches/release/tools/build/v2/example/qt/qt4/hello/Jamroot (props changed)
branches/release/tools/build/v2/example/qt/qt4/moccable-cpp/Jamroot (props changed)
branches/release/tools/build/v2/example/qt/qt4/uic/Jamroot (props changed)
branches/release/tools/build/v2/example/qt/qt4/uic/hello_world_widget.ui (props changed)
branches/release/tools/build/v2/test/boostbook/Jamroot (props changed)
branches/release/tools/build/v2/test/dependency-test/x.foo (props changed)
branches/release/tools/build/v2/test/dependency-test/y.foo (props changed)
branches/release/tools/build/v2/test/direct-request-test/Jamfile2 (props changed)
branches/release/tools/build/v2/test/generators-test/b.cxx (props changed)
branches/release/tools/build/v2/test/generators-test/c.tui (props changed)
branches/release/tools/build/v2/test/generators-test/d.wd (props changed)
branches/release/tools/build/v2/test/generators-test/x.l (props changed)
branches/release/tools/build/v2/test/generators-test/y.x_pro (props changed)
branches/release/tools/build/v2/test/prebuilt/ext/Jamfile2 (props changed)
branches/release/tools/build/v2/test/prebuilt/ext/Jamfile3 (props changed)
branches/release/tools/build/v2/test/project-test4/Jamfile3 (props changed)
branches/release/tools/build/v2/test/project-test4/Jamfile4 (props changed)
branches/release/tools/build/v2/test/project-test4/Jamfile5 (props changed)
branches/release/tools/build/v2/test/project-test4/lib/Jamfile1 (props changed)
branches/release/tools/build/v2/test/project-test4/lib/Jamfile2 (props changed)
branches/release/tools/build/v2/test/project-test4/lib/Jamfile3 (props changed)
branches/release/tools/build/v2/test/project-test4/lib2/Jamfile2 (props changed)
branches/release/tools/build/v2/test/subdir1/file-to-bind (props changed)
branches/release/tools/build/v2/test/unused/b.x (props changed)
Text files modified:
branches/release/tools/build/v2/build-system.jam | 63 ++-
branches/release/tools/build/v2/build/alias.jam | 33
branches/release/tools/build/v2/build/feature.jam | 52 ++
branches/release/tools/build/v2/build/generators.jam | 231 +++++------
branches/release/tools/build/v2/build/modifiers.jam | 78 +--
branches/release/tools/build/v2/build/project.jam | 98 ++--
branches/release/tools/build/v2/build/property-set.jam | 42 +
branches/release/tools/build/v2/build/property.jam | 65 ++-
branches/release/tools/build/v2/build/scanner.jam | 1
branches/release/tools/build/v2/build/targets.jam | 268 +++++++++-----
branches/release/tools/build/v2/build/toolset.jam | 10
branches/release/tools/build/v2/build/type.jam | 22 +
branches/release/tools/build/v2/build/version.jam | 123 ++++++
branches/release/tools/build/v2/build/virtual-target.jam | 82 +++-
branches/release/tools/build/v2/doc/src/advanced.xml | 402 ++++++++++-----------
branches/release/tools/build/v2/doc/src/extending.xml | 149 ++++----
branches/release/tools/build/v2/doc/src/fragments.xml | 59 +-
branches/release/tools/build/v2/doc/src/reference.xml | 721 ++++++++++++++++++++-------------------
branches/release/tools/build/v2/doc/src/tasks.xml | 429 ++++++++++++----------
branches/release/tools/build/v2/doc/src/tutorial.xml | 590 +++++++++++++++-----------------
branches/release/tools/build/v2/index.html | 2
branches/release/tools/build/v2/kernel/bootstrap.jam | 6
branches/release/tools/build/v2/kernel/class.jam | 195 +++++-----
branches/release/tools/build/v2/kernel/errors.jam | 12
branches/release/tools/build/v2/kernel/modules.jam | 114 +++--
branches/release/tools/build/v2/roll.sh | 2
branches/release/tools/build/v2/test/BoostBuild.py | 166 ++++++---
branches/release/tools/build/v2/test/TestCmd.py | 321 +++++++++-------
branches/release/tools/build/v2/test/build_file.py | 178 ++++++++-
branches/release/tools/build/v2/test/conditionals_multiple.py | 2
branches/release/tools/build/v2/test/example_qt4.py | 6
branches/release/tools/build/v2/test/rebuilds.py | 2
branches/release/tools/build/v2/test/test_all.py | 15
branches/release/tools/build/v2/test/test_system.html | 388 ++++++++++++--------
branches/release/tools/build/v2/test/unit_test.py | 14
branches/release/tools/build/v2/tools/acc.jam | 3
branches/release/tools/build/v2/tools/builtin.jam | 31 +
branches/release/tools/build/v2/tools/common.jam | 218 ++++++++---
branches/release/tools/build/v2/tools/como-linux.jam | 30
branches/release/tools/build/v2/tools/como-win.jam | 65 +-
branches/release/tools/build/v2/tools/como.jam | 5
branches/release/tools/build/v2/tools/darwin.jam | 275 +++++++++++---
branches/release/tools/build/v2/tools/doxygen.jam | 198 +++++-----
branches/release/tools/build/v2/tools/gcc.jam | 38 +
branches/release/tools/build/v2/tools/intel-darwin.jam | 11
branches/release/tools/build/v2/tools/intel-win.jam | 3
branches/release/tools/build/v2/tools/make.jam | 64 +-
branches/release/tools/build/v2/tools/msvc.jam | 402 ++++++++++++++--------
branches/release/tools/build/v2/tools/pathscale.jam | 4
branches/release/tools/build/v2/tools/pgi.jam | 6
branches/release/tools/build/v2/tools/python.jam | 648 ++++++++++++++++++-----------------
branches/release/tools/build/v2/tools/qt3.jam | 85 ++--
branches/release/tools/build/v2/tools/qt4.jam | 651 +++++++++++++++--------------------
branches/release/tools/build/v2/tools/quickbook.jam | 52 +-
branches/release/tools/build/v2/tools/stage.jam | 197 +++++-----
branches/release/tools/build/v2/tools/symlink.jam | 6
branches/release/tools/build/v2/tools/testing.jam | 24 +
branches/release/tools/build/v2/tools/vacpp.jam | 2
branches/release/tools/build/v2/tools/xsltproc.jam | 132 +++---
branches/release/tools/build/v2/user-config.jam | 108 +++--
branches/release/tools/build/v2/util/assert.jam | 342 ++++++++++++++----
branches/release/tools/build/v2/util/container.jam | 333 +++++++++--------
branches/release/tools/build/v2/util/doc.jam | 281 ++++++++-------
branches/release/tools/build/v2/util/indirect.jam | 5
branches/release/tools/build/v2/util/numbers.jam | 119 ++++--
branches/release/tools/build/v2/util/os.jam | 3
branches/release/tools/build/v2/util/path.jam | 247 ++++++++-----
branches/release/tools/build/v2/util/print.jam | 134 +++---
branches/release/tools/build/v2/util/sequence.jam | 77 ++-
branches/release/tools/build/v2/util/set.jam | 47 +-
branches/release/tools/build/v2/util/string.jam | 86 ++--
branches/release/tools/build/v2/util/utility.jam | 2
72 files changed, 5624 insertions(+), 4251 deletions(-)
Modified: branches/release/tools/build/v2/build-system.jam
==============================================================================
--- branches/release/tools/build/v2/build-system.jam (original)
+++ branches/release/tools/build/v2/build-system.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -242,7 +242,7 @@
}
else
{
- if ( must-find )
+ if $(must-find)
{
errors.user-error "Configuration file" "$(filename)" "not found in"
"$(path)" "." ;
@@ -253,7 +253,7 @@
"$(path)" "." ;
}
}
- return where ;
+ return $(where) ;
}
@@ -301,6 +301,11 @@
initialize-config-module test-config ;
local test-config = [ MATCH ^--test-config=(.*)$ : $(.argv) ] ;
+ local uq = [ MATCH \"(.*)\" : $(test-config) ] ;
+ if $(uq)
+ {
+ test-config = $(uq) ;
+ }
if $(test-config)
{
local where =
@@ -594,12 +599,21 @@
local cleanall ; if "--clean-all" in $(.argv) { cleanall = true ; }
- # List of Boost Build meta-targets and actual raw Jam targets directly
- # requested by the user. Raw Jam targets are used when user's request
- # contains a reference to a specific file not modeled using a main Boost
- # Build target.
+ # List of explicitly requested files to build. Any target references read
+ # from the command line parameter not recognized as one of the targets
+ # defined in the loaded Jamfiles will be interpreted as an explicitly
+ # requested file to build. If any such files are explicitly requested then
+ # only those files and the targets they depend on will be built and they
+ # will be searched for among targets that would have been built had there
+ # been no explicitly requested files.
+ local explicitly-requested-files
+
+
+ # List of Boost Build meta-targets, virtual-targets and actual Jam targets
+ # constructed in this build system run.
local targets ;
- local bjam-targets ;
+ local virtual-targets ;
+ local actual-targets ;
# Process each target specified on the command-line and convert it into
@@ -628,7 +642,7 @@
{
ECHO "notice: could not find main target" $(id) ;
ECHO "notice: assuming it's a name of file to create." ;
- bjam-targets += $(id) ;
+ explicitly-requested-files += $(id) ;
}
else
{
@@ -642,10 +656,6 @@
}
- # List of all virtual-targets created in this build system run.
- local virtual-targets ;
-
-
# Now that we have a set of targets to build and a set of property sets to
# build the targets with, we can start the main build process by using each
# property set to generate virtual targets from all of our listed targets
@@ -665,11 +675,7 @@
}
- # List of all Jam targets constructed in this build system run.
- local actual-targets ;
-
-
- # Convert all collected virtual targets into actual raw Jam targets.
+ # Convert collected virtual targets into actual raw Jam targets.
for t in $(virtual-targets)
{
actual-targets += [ $(t).actualize ] ;
@@ -851,19 +857,24 @@
}
- # TODO: See if this 'NOTFILE all' statement can be moved below to the
- # default case where the 'all' target is actually requested to be built.
- # Check for other Jam scripts manually setting a dependency for this target.
+ # The 'all' pseudo target is not strictly needed expect in the case when we
+ # use it below but people often assume they always have this target
+ # available and do not declare it themselves before use which may cause
+ # build failures with an error message about not being able to build the
+ # 'all' target.
NOTFILE all ;
# And now that all the actual raw Jam targets and all the dependencies
- # between them have been prepared (or we have everything set so we can
- # easily prepare them) all that is left is to tell Jam to update those
- # targets.
- if $(bjam-targets)
- {
- UPDATE $(bjam-targets:G=e) $(.out-xml) ;
+ # between them have been prepared all that is left is to tell Jam to update
+ # those targets.
+ if $(explicitly-requested-files)
+ {
+ # Note that this case can not be joined with the regular one when only
+ # exact Boost Build targets are requested as here we do not build those
+ # requested targets but only use them to construct the dependency tree
+ # needed to build the explicitly requested files.
+ UPDATE $(explicitly-requested-files:G=e) $(.out-xml) ;
}
else if $(cleanall)
{
Modified: branches/release/tools/build/v2/build/alias.jam
==============================================================================
--- branches/release/tools/build/v2/build/alias.jam (original)
+++ branches/release/tools/build/v2/build/alias.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -2,27 +2,26 @@
# 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)
-# This module defines the 'alias' rule and the associated target class.
+# This module defines the 'alias' rule and the associated target class.
#
-# Alias is just a main target which returns its source targets without any
-# processing. For example:
+# Alias is just a main target which returns its source targets without any
+# processing. For example:
#
-# alias bin : hello test_hello ;
-# alias lib : helpers xml_parser ;
+# alias bin : hello test_hello ;
+# alias lib : helpers xml_parser ;
#
-# Another important use of 'alias' is to conveniently group source files:
+# Another important use of 'alias' is to conveniently group source files:
#
-# alias platform-src : win.cpp : <os>NT ;
-# alias platform-src : linux.cpp : <os>LINUX ;
-# exe main : main.cpp platform-src ;
+# alias platform-src : win.cpp : <os>NT ;
+# alias platform-src : linux.cpp : <os>LINUX ;
+# exe main : main.cpp platform-src ;
#
-# Lastly, it's possible to create local alias for some target, with different
-# properties::
+# Lastly, it is possible to create a local alias for some target, with different
+# properties:
#
-# alias big_lib : : @/external_project/big_lib/<link>static ;
+# alias big_lib : : @/external_project/big_lib/<link>static ;
#
-
import "class" : new ;
import project ;
import property-set ;
@@ -47,12 +46,14 @@
{
local base = [ basic-target.compute-usage-requirements $(subvariant) ] ;
# Add source's usage requirement. If we don't do this, "alias" does not
- # look like 100% alias.
+ # look like a 100% alias.
return [ $(base).add [ $(subvariant).sources-usage-requirements ] ] ;
}
}
+
# Declares the 'alias' target. It will build sources, and return them unaltered.
+#
rule alias ( name : sources * : requirements * : default-build * : usage-requirements * )
{
local project = [ project.current ] ;
@@ -66,7 +67,5 @@
] ;
}
-IMPORT $(__name__) : alias : : alias ;
-
-
+IMPORT $(__name__) : alias : : alias ;
Modified: branches/release/tools/build/v2/build/feature.jam
==============================================================================
--- branches/release/tools/build/v2/build/feature.jam (original)
+++ branches/release/tools/build/v2/build/feature.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -19,7 +19,6 @@
{
.all-attributes =
implicit
- executed
composite
optional
symmetric
@@ -43,6 +42,7 @@
# Prepare a fresh space to test in by moving all global variable settings into
# the given temporary module and erasing them here.
+#
rule prepare-test ( temp-module )
{
DELETE_MODULE $(temp-module) ;
@@ -62,6 +62,7 @@
# Clear out all global variables and recover all variables from the given
# temporary module.
+#
rule finish-test ( temp-module )
{
# Clear globals.
@@ -81,8 +82,9 @@
}
-# Transform features by bracketing any elements which aren't already bracketed
+# Transform features by bracketing any elements which are not already bracketed
# by "<>".
+#
local rule grist ( features * )
{
local empty = "" ;
@@ -91,6 +93,7 @@
# Declare a new feature with the given name, values, and attributes.
+#
rule feature (
name # Feature name.
: values * # Allowable values - may be extended later using feature.extend.
@@ -119,6 +122,14 @@
{
error = free features cannot be propagated ;
}
+ else
+ {
+ local m = [ MATCH (.*=.*) : $(values) ] ;
+ if $(m[1])
+ {
+ error = "feature value may not contain '='" ;
+ }
+ }
if $(error)
{
@@ -146,6 +157,7 @@
# Sets the default value of the given feature, overriding any previous default.
+#
rule set-default ( feature : value )
{
local f = [ grist $(feature) ] ;
@@ -159,6 +171,7 @@
# Returns the default property values for the given features.
+#
rule defaults ( features * )
{
local result ;
@@ -179,6 +192,7 @@
# Returns true iff all 'names' elements are valid features.
+#
rule valid ( names + )
{
if $(names) in $(.all-features)
@@ -189,6 +203,7 @@
# Returns the attibutes of the given feature.
+#
rule attributes ( feature )
{
return $($(:E=:G=$(feature)).attributes) ;
@@ -196,6 +211,7 @@
# Returns the values of the given feature.
+#
rule values ( feature )
{
return $($(:E=:G=$(feature)).values) ;
@@ -203,6 +219,7 @@
# Returns true iff 'value-string' is a value-string of an implicit feature.
+#
rule is-implicit-value ( value-string )
{
local v = [ regex.split $(value-string) - ] ;
@@ -231,6 +248,7 @@
# Returns the implicit feature associated with the given implicit value.
+#
rule implied-feature ( implicit-value )
{
local components = [ regex.split $(implicit-value) "-" ] ;
@@ -260,6 +278,7 @@
# Given a feature and a value of one of its subfeatures, find the name of the
# subfeature. If value-string is supplied, looks for implied subfeatures that
# are specific to that value of feature
+#
rule implied-subfeature (
feature # The main feature name.
subvalue # The value of one of its subfeatures.
@@ -279,6 +298,7 @@
# Generate an error if the feature is unknown.
+#
local rule validate-feature ( feature )
{
if ! $(feature) in $(.all-features)
@@ -298,6 +318,7 @@
# return:
#
# <toolset>gcc <toolset-version>2.95.2 <toolset-os>linux <toolset-cpu>x86
+#
local rule expand-subfeatures-aux (
feature ? # Feature name or empty if value corresponds to an
# implicit property.
@@ -392,6 +413,7 @@
# Helper for extend, below. Handles the feature case.
+#
local rule extend-feature ( feature : values * )
{
feature = [ grist $(feature) ] ;
@@ -420,6 +442,7 @@
# Checks that value-string is a valid value-string for the given feature.
+#
rule validate-value-string ( feature value-string )
{
if ! (
@@ -457,6 +480,7 @@
# between subvalue(s) and a subfeature
# * value of that variable when such a subfeature/subvalue has been defined and
# returns a list consisting of the latter followed by the former.
+#
local rule subvalue-var (
feature # Main feature name.
value-string ? # If supplied, specifies a specific value of the main
@@ -511,6 +535,7 @@
# Returns true iff the subvalues are valid for the feature. When the optional
# value-string is provided, returns true iff the subvalues are valid for the
# given value of the feature.
+#
rule is-subvalue ( feature : value-string ? : subfeature : subvalue )
{
local subfeature-vars = [ subvalue-var $(feature) $(value-string)
@@ -584,6 +609,7 @@
# Declares a subfeature.
+#
rule subfeature (
feature # Root feature that is not a subfeature.
value-string ? # A value-string specifying which feature or subfeature
@@ -616,6 +642,7 @@
# Set components of the given composite property.
+#
rule compose ( composite-property : component-properties * )
{
local feature = $(composite-property:G) ;
@@ -647,6 +674,7 @@
# Return all values of the given feature specified by the given property set.
+#
rule get-values ( feature : properties * )
{
local result ;
@@ -674,6 +702,7 @@
# Expand all composite properties in the set so that all components are
# explicitly expressed.
+#
rule expand-composites ( properties * )
{
local explicit-features = $(properties:G) ;
@@ -732,6 +761,7 @@
# Return true iff f is an ordinary subfeature of the parent-property's feature,
# or if f is a subfeature of the parent-property's feature specific to the
# parent-property's value.
+#
local rule is-subfeature-of ( parent-property f )
{
if subfeature in $($(f).attributes)
@@ -762,6 +792,7 @@
# As for is-subfeature-of but for subproperties.
+#
local rule is-subproperty-of ( parent-property p )
{
return [ is-subfeature-of $(parent-property) $(p:G) ] ;
@@ -771,6 +802,7 @@
# Given a property, return the subset of features consisting of all ordinary
# subfeatures of the property's feature, and all specific subfeatures of the
# property's feature which are conditional on the property's value.
+#
local rule select-subfeatures ( parent-property : features * )
{
return [ sequence.filter is-subfeature-of $(parent-property) : $(features) ] ;
@@ -778,6 +810,7 @@
# As for select-subfeatures but for subproperties.
+#
local rule select-subproperties ( parent-property : properties * )
{
return [ sequence.filter is-subproperty-of $(parent-property) : $(properties) ] ;
@@ -792,6 +825,7 @@
# of those features due to composite feature expansion to be dropped. If two
# values of a given non-free feature are directly expressed in the input, an
# error is issued.
+#
rule expand ( properties * )
{
local expanded = [ expand-subfeatures $(properties) ] ;
@@ -801,6 +835,7 @@
# Helper rule for minimize. Returns true iff property's feature is present in
# the contents of the variable named by feature-set-var.
+#
local rule in-features ( feature-set-var property )
{
if $(property:G) in $($(feature-set-var))
@@ -812,6 +847,7 @@
# Helper rule for minimize. Returns the list with the same properties, but with
# all subfeatures moved to the end of the list.
+#
local rule move-subfeatures-to-the-end ( properties * )
{
local x1 ;
@@ -837,6 +873,7 @@
# they override a value from some composite property. Implicit properties will
# be expressed without feature grist, and sub-property values will be expressed
# as elements joined to the corresponding main property.
+#
rule minimize ( properties * )
{
# Precondition checking
@@ -906,8 +943,9 @@
# Requires: for every subproperty, there is a parent property. All features are
# explicitly expressed.
#
-# This rule probably shouldn't be needed, but build-request.expand-no-defaults
+# This rule probably should not be needed, but build-request.expand-no-defaults
# is being abused for unintended purposes and it needs help.
+#
rule compress-subproperties ( properties * )
{
local all-subs ;
@@ -919,7 +957,7 @@
if ! $(p:G)
{
# Expecting fully-gristed properties.
- assert.nonempty-variable p:G ;
+ assert.variable-not-empty p:G ;
}
if ! subfeature in $($(p:G).attributes)
@@ -947,6 +985,7 @@
# feature name followed by a dash, and return a pair consisting of the parts
# before and after that dash. More interesting than a simple split because
# feature names may contain dashes.
+#
local rule split-top-feature ( feature-plus )
{
local e = [ regex.split $(feature-plus) - ] ;
@@ -982,6 +1021,7 @@
# <variant>debug <runtime_debugging>off
#
# and that's kind of strange.
+#
rule add-defaults ( properties * )
{
for local v in $(properties:G=)
@@ -1026,6 +1066,7 @@
# Note that vN...vM may contain slashes. This needs to be resilient to the
# substitution of backslashes for slashes, since Jam, unbidden, sometimes swaps
# slash direction on NT.
+#
rule split ( property-set )
{
local pieces = [ regex.split $(property-set) [\\/] ] ;
@@ -1048,7 +1089,8 @@
# Tests of module feature.
-local rule __test__ ( )
+#
+rule __test__ ( )
{
# Use a fresh copy of the feature module.
prepare-test feature-test-temp ;
Modified: branches/release/tools/build/v2/build/generators.jam
==============================================================================
--- branches/release/tools/build/v2/build/generators.jam (original)
+++ branches/release/tools/build/v2/build/generators.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -5,46 +5,37 @@
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
-# Manages 'generators' --- objects which can do transformation between
-# different target types and contain algorithm for finding transformation from
-# sources to targets.
-#
-# The main entry point to this module is generators.construct rule. It is given
-# a list of source targets, desired target type and a set of properties. It
-# starts by selecting 'viable generators', which have any chances of producing
-# the desired target type with the required properties. Generators are ranked
-# and a set of the most specific ones is selected.
-#
-# The most specific generators have their 'run' methods called, with the
-# properties and list of sources. Each one selects a target which can be
-# directly consumed, and tries to convert the remaining ones to the types it
-# can consume. This is done by recursively calling 'construct' with all
-# consumable types.
-#
-# If the generator has collected all the targets it needs, it creates targets
-# corresponding to result, and returns it. When all generators have been run,
-# results of one of them are selected and returned as a result.
-#
-# It's quite possible that 'construct' returns more targets that it was asked
-# for. For example, it was asked to target type EXE, but the only found
-# generators produces both EXE and TDS (file with debug) information. The extra
-# target will be returned.
-#
-# Likewise, when generator tries to convert sources to consumable types, it can
-# get more targets that it was asked for. The question is what to do with extra
-# targets. Boost.Build attempts to convert them to requested types, and
-# attempts that as early as possible. Specifically, this is done after invoking
-# each generator. (Later I'll document the rationale for trying extra target
-# conversion at that point).
-#
-# That early conversion is not always desirable. Suppose a generator got a
-# source of type Y and must consume one target of type X_1 and one target of
-# type X_2. When converting Y to X_1 extra target of type Y_2 is created. We
-# should not try to convert it to type X_1, because if we do so, the generator
-# will get two targets of type X_1, and will be at loss as to which one to use.
-# Because of that, the 'construct' rule has a parameter, telling if multiple
-# targets can be returned. If the parameter is false, conversion of extra
-# targets is not performed.
+# Manages 'generators' --- objects which can do transformation between different
+# target types and contain algorithm for finding transformation from sources to
+# targets.
+#
+# The main entry point to this module is generators.construct rule. It is given
+# a list of source targets, desired target type and a set of properties. It
+# starts by selecting 'viable generators', which have any chances of producing
+# the desired target type with the required properties. Generators are ranked
+# and a set of the most specific ones is selected.
+#
+# The most specific generators have their 'run' methods called, with the
+# properties and list of sources. Each one selects a target which can be
+# directly consumed, and tries to convert the remaining ones to the types it can
+# consume. This is done by recursively calling 'construct' with all consumable
+# types.
+#
+# If the generator has collected all the targets it needs, it creates targets
+# corresponding to result, and returns it. When all generators have been run,
+# results of one of them are selected and returned as a result.
+#
+# It is quite possible for 'construct' to return more targets that it was asked
+# for. For example, if it were asked to generate a target of type EXE, but the
+# only found generator produces both EXE and TDS (file with debug) information.
+# The extra target will be returned.
+#
+# Likewise, when generator tries to convert sources to consumable types, it can
+# get more targets that it was asked for. The question is what to do with extra
+# targets. Boost.Build attempts to convert them to requested types, and attempts
+# that as early as possible. Specifically, this is done after invoking each
+# generator. TODO: An example is needed to document the rationale for trying
+# extra target conversion at that point.
import "class" : new ;
import errors ;
@@ -93,8 +84,8 @@
# Takes a vector of 'virtual-target' instances and makes a normalized
-# representation, which is the same for given set of targets,
-# regardless of their order.
+# representation, which is the same for given set of targets, regardless of
+# their order.
#
rule normalize-target-list ( targets )
{
@@ -183,19 +174,19 @@
return $(self.source-types) ;
}
- # Returns the list of target types that this generator produces.
- # It is assumed to be always the same -- i.e. it cannot change depending
- # list of sources.
+ # Returns the list of target types that this generator produces. It is
+ # assumed to be always the same -- i.e. it cannot change depending list of
+ # sources.
#
rule target-types ( )
{
return $(self.target-types) ;
}
- # Returns the required properties for this generator. Properties
- # in returned set must be present in build properties if this
- # generator is to be used. If result has grist-only element,
- # that build properties must include some value of that feature.
+ # Returns the required properties for this generator. Properties in returned
+ # set must be present in build properties if this generator is to be used.
+ # If result has grist-only element, that build properties must include some
+ # value of that feature.
# XXX: remove this method?
#
rule requirements ( )
@@ -208,10 +199,9 @@
#
rule match-rank ( property-set-to-match )
{
- # See if generator's requirements are satisfied by
- # 'properties'. Treat a feature name in requirements
- # (i.e. grist-only element), as matching any value of the
- # feature.
+ # See if generator's requirements are satisfied by 'properties'. Treat a
+ # feature name in requirements (i.e. grist-only element), as matching
+ # any value of the feature.
local all-requirements = [ requirements ] ;
local property-requirements feature-requirements ;
@@ -239,9 +229,9 @@
}
}
- # Returns another generator which differers from $(self) in
- # - id
- # - value to <toolset> feature in properties
+ # Returns another generator which differs from $(self) in
+ # - id
+ # - value to <toolset> feature in properties
#
rule clone ( new-id : new-toolset-properties + )
{
@@ -287,14 +277,13 @@
# run indicates that the generator was unable to create the target.
#
rule run ( project # Project for which the targets are generated
- name ? # Determines the name of 'name' attribute for
- # all generated targets. See 'generated-targets' method.
+ name ? # Determines the name of 'name' attribute for all
+ # generated targets. See 'generated-targets' method.
: property-set # Desired properties for generated targets.
: sources + # Source targets.
)
{
generators.dout [ indent ] " ** generator" $(self.id) ;
- generators.dout [ indent ] " multiple:" $(mutliple) ;
generators.dout [ indent ] " composing:" $(self.composing) ;
if ! $(self.composing) && $(sources[2]) && $(self.source-types[2])
@@ -360,15 +349,16 @@
rule construct-result (
consumed + # Already prepared list of consumable targets
# If generator requires several source files will contain
- # exactly len $(self.source-types) targets with matching types
- # Otherwise, might contain several targets with the type of
- # $(self.source-types[1])
+ # exactly len $(self.source-types) targets with matching
+ # types. Otherwise, might contain several targets with the
+ # type of $(self.source-types[1]).
: project name ?
: property-set # Properties to be used for all actions create here.
)
{
local result ;
- # If this is 1->1 transformation, apply it to all consumed targets in order.
+ # If this is 1->1 transformation, apply it to all consumed targets in
+ # order.
if ! $(self.source-types[2]) && ! $(self.composing)
{
for local r in $(consumed)
@@ -391,15 +381,14 @@
#
rule determine-output-name ( sources + )
{
- # The simple case if when a name
- # of source has single dot. Then, we take the part before
- # dot. Several dots can be caused by:
- # - Using source file like a.host.cpp
- # - A type which suffix has a dot. Say, we can
- # type 'host_cpp' with extension 'host.cpp'.
- # In the first case, we want to take the part till the last
- # dot. In the second case -- no sure, but for now take
- # the part till the last dot too.
+ # The simple case if when a name of source has single dot. Then, we take
+ # the part before dot. Several dots can be caused by:
+ # - Using source file like a.host.cpp
+ # - A type which suffix has a dot. Say, we can type 'host_cpp' with
+ # extension 'host.cpp'.
+ # In the first case, we want to take the part up to the last dot. In the
+ # second case -- no sure, but for now take the part up to the last dot
+ # too.
name = [ utility.basename [ $(sources[1]).name ] ] ;
for local s in $(sources[2])
@@ -429,13 +418,13 @@
# the '%' symbol in the name pattern will be replaced with the 'name'
# parameter to obtain the 'name' attribute.
#
- # For example, if targets types are T1 and T2(with name pattern "%_x"),
- # suffixes for T1 and T2 are .t1 and t2, and source if foo.z, then created
+ # For example, if targets types are T1 and T2 (with name pattern "%_x"),
+ # suffixes for T1 and T2 are .t1 and .t2, and source is foo.z, then created
# files would be "foo.t1" and "foo_x.t2". The 'name' attribute actually
# determines the basename of a file.
#
# Note that this pattern mechanism has nothing to do with implicit patterns
- # in make. It's a way to produce target which name is different for name of
+ # in make. It is a way to produce target which name is different for name of
# source.
#
rule generated-targets ( sources + : property-set : project name ? )
@@ -460,16 +449,16 @@
pre = $(pre[2-]) ;
post = $(post[2-]) ;
- targets += [ class.new file-target $(generated-name)
- : $(t) : $(project) : $(a) ] ;
+ targets += [ class.new file-target $(generated-name) : $(t) :
+ $(project) : $(a) ] ;
}
return [ sequence.transform virtual-target.register : $(targets) ] ;
}
- # Attempts to convert 'source' to the types that this generator can
- # handle. The intention is to produce the set of targets can should be
- # used when generator is run.
+ # Attempts to convert 'source' to the types that this generator can handle.
+ # The intention is to produce the set of targets can should be used when
+ # generator is run.
#
rule convert-to-consumable-types ( project name ? :
property-set : sources +
@@ -481,16 +470,16 @@
# cannot be consumed
)
{
- # We're likely to be passed 'consumed' and 'bypassed'
- # var names. Use "_" to avoid name conflicts.
+ # We're likely to be passed 'consumed' and 'bypassed' var names. Use "_"
+ # to avoid name conflicts.
local _consumed ;
local _bypassed ;
local missing-types ;
if $(sources[2])
{
- # Don't know how to handle several sources yet. Just try
- # to pass the request to other generator
+ # Don't know how to handle several sources yet. Just try to pass the
+ # request to other generator
missing-types = $(self.source-types) ;
}
else
@@ -498,18 +487,17 @@
consume-directly $(sources) : _consumed : missing-types ;
}
- # No need to search for transformation if
- # some source type has consumed source and
- # no more source types are needed.
+ # No need to search for transformation if some source type has consumed
+ # source and no more source types are needed.
if $(only-one) && $(_consumed)
{
missing-types = ;
}
- #TODO: we should check that only one source type
- #if create of 'only-one' is true.
- # TODO: consider if consuned/bypassed separation should
- # be done by 'construct-types'.
+ # TODO: we should check that only one source type if create of
+ # 'only-one' is true.
+ # TODO: consider if consumed/bypassed separation should be done by
+ # 'construct-types'.
if $(missing-types)
{
@@ -538,15 +526,14 @@
_consumed = [ sequence.unique $(_consumed) ] ;
_bypassed = [ sequence.unique $(_bypassed) ] ;
- # remove elements of '_bypassed' that are in '_consumed'
+ # Remove elements of '_bypassed' that are in '_consumed'.
- # Suppose the target type of current generator, X is produced from
- # X_1 and X_2, which are produced from Y by one generator.
- # When creating X_1 from Y, X_2 will be added to 'bypassed'
- # Likewise, when creating X_2 from Y, X_1 will be added to 'bypassed'
- # But they are also in 'consumed'. We have to remove them from
- # bypassed, so that generators up the call stack don't try to convert
- # them.
+ # Suppose the target type of current generator, X is produced from X_1
+ # and X_2, which are produced from Y by one generator. When creating X_1
+ # from Y, X_2 will be added to 'bypassed'. Likewise, when creating X_2
+ # from Y, X_1 will be added to 'bypassed', but they are also in
+ # 'consumed'. We have to remove them from bypassed, so that generators
+ # up the call stack don't try to convert them.
# In this particular case, X_1 instance in 'consumed' and X_1 instance
# in 'bypassed' will be the same: because they have the same source and
@@ -555,7 +542,6 @@
_bypassed = [ set.difference $(_bypassed) : $(_consumed) ] ;
-
$(consumed-var) += $(_consumed) ;
$(bypassed-var) += $(_bypassed) ;
}
@@ -565,8 +551,8 @@
rule convert-multiple-sources-to-consumable-types
( project : property-set : sources * : consumed-var bypassed-var )
{
- # We process each source one-by-one, trying to convert it to
- # a usable type.
+ # We process each source one-by-one, trying to convert it to a usable
+ # type.
for local source in $(sources)
{
local _c ;
@@ -587,7 +573,7 @@
{
local real-source-type = [ $(source).type ] ;
- # If there are no source types, we can consume anything
+ # If there are no source types, we can consume anything.
local source-types = $(self.source-types) ;
source-types ?= $(real-source-type) ;
@@ -606,8 +592,8 @@
}
}
- # Returns the class to be used to actions. Default implementation
- # returns "action".
+ # Returns the class to be used to actions. Default implementation returns
+ # "action".
#
rule action-class ( )
{
@@ -625,10 +611,9 @@
{
.generators += $(g) ;
- # A generator can produce several targets of the
- # same type. We want unique occurence of that generator
- # in .generators.$(t) in that case, otherwise, it will
- # be tried twice and we'll get false ambiguity.
+ # A generator can produce several targets of the same type. We want unique
+ # occurence of that generator in .generators.$(t) in that case, otherwise,
+ # it will be tried twice and we'll get false ambiguity.
for local t in [ sequence.unique [ $(g).target-types ] ]
{
.generators.$(t) += $(g) ;
@@ -636,20 +621,17 @@
# Update the set of generators for toolset
- # TODO: should we check that generator with this id
- # is not already registered. For example, the fop.jam
- # module intentionally declared two generators with the
- # same id, so such check will break it.
+ # TODO: should we check that generator with this id is not already
+ # registered. For example, the fop.jam module intentionally declared two
+ # generators with the same id, so such check will break it.
local id = [ $(g).id ] ;
- # Some generators have multiple periods in their name, so the
- # normal $(id:S=) won't generate the right toolset name.
- # e.g. if id = gcc.compile.c++, then
- # .generators-for-toolset.$(id:S=) will append to
- # .generators-for-toolset.gcc.compile, which is a separate
- # value from .generators-for-toolset.gcc. Correcting this
- # makes generator inheritance work properly.
- # See also inherit-generators in module toolset
+ # Some generators have multiple periods in their name, so the normal
+ # $(id:S=) won't generate the right toolset name. E.g. if id =
+ # = gcc.compile.c++, then .generators-for-toolset.$(id:S=) will append to
+ # .generators-for-toolset.gcc.compile, which is a separate value from
+ # .generators-for-toolset.gcc. Correcting this makes generator inheritance
+ # work properly. See also inherit-generators in the toolset module.
local base = $(id) ;
while $(base:S)
{
@@ -729,8 +711,8 @@
# 't' is the list of types which have not yet been processed.
while $(t)
{
- # Find all generators for current type.
- # Unlike 'find-viable-generators' we don't care about property-set.
+ # Find all generators for current type. Unlike 'find-viable-generators'
+ # we don't care about property-set.
local generators = $(.generators.$(t[1])) ;
t = $(t[2-]) ;
@@ -1171,8 +1153,7 @@
# Attempts to create a target of 'target-type' with 'properties' from 'sources'.
# The 'sources' are treated as a collection of *possible* ingridients -- i.e. it
-# is not required to consume them all. If 'multiple' is true, the rule is
-# allowed to return several targets of 'target-type'.
+# is not required to consume them all.
#
# Returns a list of targets. When this invocation is first instance of
# 'construct' in stack, returns only targets of requested 'target-type',
Modified: branches/release/tools/build/v2/build/modifiers.jam
==============================================================================
--- branches/release/tools/build/v2/build/modifiers.jam (original)
+++ branches/release/tools/build/v2/build/modifiers.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -30,7 +30,7 @@
id
composing ?
: source-types *
- : target-types-and-names +
+ : target-types-and-names +
: requirements *
)
{
@@ -38,14 +38,14 @@
: $(source-types)
: $(target-types-and-names)
: $(requirements) ;
-
+
self.targets-in-progress = ;
}
-
+
# Wraps the generation of the target to call before and after rules to
# affect the real target.
#
- rule run ( project name ? : property-set : sources + : multiple ? )
+ rule run ( project name ? : property-set : sources + )
{
local result ;
local current-target = $(project)^$(name) ;
@@ -54,77 +54,67 @@
# Before modifications...
local project_ =
[ modify-project-before
- $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+ $(project) $(name) : $(property-set) : $(sources) ] ;
local name_ =
[ modify-name-before
- $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+ $(project) $(name) : $(property-set) : $(sources) ] ;
local property-set_ =
[ modify-properties-before
- $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+ $(project) $(name) : $(property-set) : $(sources) ] ;
local sources_ =
[ modify-sources-before
- $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
- local multiple_ =
- [ modify-multiple-before
- $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+ $(project) $(name) : $(property-set) : $(sources) ] ;
project = $(project_) ;
name = $(name_) ;
property-set = $(property-set_) ;
sources = $(sources_) ;
- multiple = $(multiple_) ;
-
+
# Generate the real target...
local target-type-p =
[ property.select <main-target-type> : [ $(property-set).raw ] ] ;
self.targets-in-progress += $(current-target) ;
result =
[ generators.construct $(project) $(name)
- : $(target-type-p:G=) $(multiple)
+ : $(target-type-p:G=)
: $(property-set)
: $(sources) ] ;
self.targets-in-progress = $(self.targets-in-progress[1--2]) ;
-
+
# After modifications...
result =
[ modify-target-after $(result)
: $(project) $(name)
: $(property-set)
- : $(sources)
- : $(multiple) ] ;
+ : $(sources) ] ;
}
return $(result) ;
}
-
- rule modify-project-before ( project name ? : property-set : sources + : multiple ? )
+
+ rule modify-project-before ( project name ? : property-set : sources + )
{
return $(project) ;
}
-
- rule modify-name-before ( project name ? : property-set : sources + : multiple ? )
+
+ rule modify-name-before ( project name ? : property-set : sources + )
{
return $(name) ;
}
-
- rule modify-properties-before ( project name ? : property-set : sources + : multiple ? )
+
+ rule modify-properties-before ( project name ? : property-set : sources + )
{
return $(property-set) ;
}
-
- rule modify-sources-before ( project name ? : property-set : sources + : multiple ? )
+
+ rule modify-sources-before ( project name ? : property-set : sources + )
{
return $(sources) ;
}
-
- rule modify-multiple-before ( project name ? : property-set : sources + : multiple ? )
- {
- return $(multiple) ;
- }
-
- rule modify-target-after ( target : project name ? : property-set : sources + : multiple ? )
+
+ rule modify-target-after ( target : project name ? : property-set : sources + )
{
return $(target) ;
}
-
+
# Utility, clones a file-target with optional changes to the name, type and
# project of the target.
# NOTE: This functionality should be moved, and generalized, to
@@ -137,19 +127,19 @@
new-type ?= [ $(target).type ] ;
new-project ?= [ $(target).project ] ;
local result = [ new file-target $(new-name) : $(new-type) : $(new-project) ] ;
-
+
if [ $(target).dependencies ] { $(result).depends [ $(target).dependencies ] ; }
$(result).root [ $(target).root ] ;
$(result).set-usage-requirements [ $(target).usage-requirements ] ;
-
+
local action = [ $(target).action ] ;
local action-class = [ modules.peek $(action) : __class__ ] ;
-
+
local ps = [ $(action).properties ] ;
- local cloned-action = [ new $(action-class) $(result) :
+ local cloned-action = [ new $(action-class) $(result) :
[ $(action).sources ] : [ $(action).action-name ] : $(ps) ] ;
$(result).action $(cloned-action) ;
-
+
return $(result) ;
}
}
@@ -167,13 +157,13 @@
# Apply ourselves to EXE targets, for now.
modifier.__init__ name.modifier : : EXE LIB : <name-modify>yes ;
}
-
+
# Modifies the name, by cloning the target with the new name.
#
- rule modify-target-after ( target : project name ? : property-set : sources + : multiple ? )
+ rule modify-target-after ( target : project name ? : property-set : sources + )
{
local result = $(target) ;
-
+
local name-mod-p = [ property.select <name-modifier> : [ $(property-set).raw ] ] ;
if $(name-mod-p)
{
@@ -190,10 +180,10 @@
: [ property-set.create [ $(property-set).raw ] <symlink-location>build-relative ] ] ;
}
}
-
+
return $(result) ;
}
-
+
# Do the transformation of the name.
#
rule modify-name ( name : modifier-spec + )
@@ -218,7 +208,7 @@
new-name-parts += $(name-parts) ;
return [ sequence.join $(new-name-parts) ] ;
}
-
+
rule optional-properties ( )
{
return <name-modify>yes ;
Modified: branches/release/tools/build/v2/build/project.jam
==============================================================================
--- branches/release/tools/build/v2/build/project.jam (original)
+++ branches/release/tools/build/v2/build/project.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -4,36 +4,35 @@
# 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)
-# Implements project representation and loading. Each project is represented
-# by:
-# - a module where all the Jamfile content live.
-# - an instance of 'project-attributes' class.
-# (given a module name, can be obtained using the 'attributes' rule)
-# - an instance of 'project-target' class (from targets.jam)
-# (given a module name, can be obtained using the 'target' rule)
-#
-# Typically, projects are created as result of loading a Jamfile, which is done
-# by rules 'load' and 'initialize', below. First, module for Jamfile is loaded
-# and new project-attributes instance is created. Some rules necessary for
-# project are added to the module (see 'project-rules' module) at the bottom of
-# this file. Default project attributes are set (inheriting attributes of
-# parent project, if it exists). After that the Jamfile is read. It can declare
-# its own attributes using the 'project' rule which will be combined with any
-# alread set attributes.
-#
-# The 'project' rule can also declare a project id which will be associated
-# with the project module.
-#
-# There can also be 'standalone' projects. They are created by calling
-# 'initialize' on an arbitrary module and not specifying their location. After
-# the call, the module can call the 'project' rule, declare main targets and
-# behave as a regular project except that, since it's not associated with any
-# location, it should not declare targets that are not prebuilt.
-#
-# The list of all loaded Jamfile is stored in the .project-locations variable.
-# It's possible to obtain a module name for a location using the 'module-name'
-# rule. Standalone projects are not recorded and can only be referenced using
-# their project id.
+# Implements project representation and loading. Each project is represented by:
+# - a module where all the Jamfile content live.
+# - an instance of 'project-attributes' class.
+# (given a module name, can be obtained using the 'attributes' rule)
+# - an instance of 'project-target' class (from targets.jam)
+# (given a module name, can be obtained using the 'target' rule)
+#
+# Typically, projects are created as result of loading a Jamfile, which is done
+# by rules 'load' and 'initialize', below. First, module for Jamfile is loaded
+# and new project-attributes instance is created. Some rules necessary for
+# project are added to the module (see 'project-rules' module) at the bottom of
+# this file. Default project attributes are set (inheriting attributes of parent
+# project, if it exists). After that the Jamfile is read. It can declare its own
+# attributes using the 'project' rule which will be combined with any already
+# set attributes.
+#
+# The 'project' rule can also declare a project id which will be associated with
+# the project module.
+#
+# There can also be 'standalone' projects. They are created by calling
+# 'initialize' on an arbitrary module and not specifying their location. After
+# the call, the module can call the 'project' rule, declare main targets and
+# behave as a regular project except that, since it is not associated with any
+# location, it should not declare targets that are not prebuilt.
+#
+# The list of all loaded Jamfile is stored in the .project-locations variable.
+# It is possible to obtain a module name for a location using the 'module-name'
+# rule. Standalone projects are not recorded and can only be referenced using
+# their project id.
import "class" : new ;
import errors ;
@@ -94,13 +93,14 @@
# Note the use of character groups, as opposed to listing 'Jamroot' and
-# 'jamroot'. With the latter, we'd get duplicate matches on Windows and would
-# have to eliminate duplicates.
+# 'jamroot'. With the latter, we would get duplicate matches on Windows and
+# would have to eliminate duplicates.
JAMROOT ?= [ modules.peek : JAMROOT ] ;
JAMROOT ?= project-root.jam [Jj]amroot [Jj]amroot.jam ;
# Loads parent of Jamfile at 'location'. Issues an error if nothing is found.
+#
rule load-parent ( location )
{
local found = [ path.glob-in-parents $(location) :
@@ -120,6 +120,7 @@
# Makes the specified 'module' act as if it were a regularly loaded Jamfile at
# 'location'. Reports an error if a Jamfile has already been loaded for that
# location.
+#
rule act-as-jamfile ( module : location )
{
if [ module-name $(location) ] in $(.jamfile-modules)
@@ -139,6 +140,7 @@
# Returns the project module corresponding to the given project-id or plain
# directory name. Returns nothing if such a project can not be found.
+#
rule find ( name : current-location )
{
local project-module ;
@@ -489,6 +491,7 @@
# Make 'project-module' inherit attributes of project root and parent module.
+#
rule inherit-attributes ( project-module : parent-module )
{
local attributes = $($(project-module).attributes) ;
@@ -528,6 +531,7 @@
# Associate the given id with the given project module.
+#
rule register-id ( id : module )
{
$(id).jamfile-module = $(module) ;
@@ -538,6 +542,7 @@
#
# The standard attributes are "id", "location", "project-root", "parent"
# "requirements", "default-build", "source-location" and "projects-to-build".
+#
class project-attributes
{
import property ;
@@ -556,6 +561,7 @@
# Set the named attribute from the specification given by the user. The
# value actually set may be different.
+ #
rule set ( attribute : specification *
: exact ? # Sets value from 'specification' without any processing.
)
@@ -640,12 +646,14 @@
}
# Returns the value of the given attribute.
+ #
rule get ( attribute )
{
return $(self.$(attribute)) ;
}
# Prints the project attributes.
+ #
rule print ( )
{
local id = $(self.id) ; id ?= (none) ;
@@ -664,6 +672,7 @@
# Returns the project which is currently being loaded.
+#
rule current ( )
{
return $(.current-project) ;
@@ -672,6 +681,7 @@
# Temporarily changes the current project to 'project'. Should be followed by
# 'pop-current'.
+#
rule push-current ( project )
{
.saved-current-project += $(.current-project) ;
@@ -687,6 +697,7 @@
# Returns the project-attribute instance for the specified Jamfile module.
+#
rule attributes ( project )
{
return $($(project).attributes) ;
@@ -694,6 +705,7 @@
# Returns the value of the specified attribute in the specified Jamfile module.
+#
rule attribute ( project attribute )
{
return [ $($(project).attributes).get $(attribute) ] ;
@@ -701,6 +713,7 @@
# Returns the project target corresponding to the 'project-module'.
+#
rule target ( project-module )
{
if ! $(.target.$(project-module))
@@ -714,6 +727,7 @@
# Use/load a project.
+#
rule use ( id : location )
{
local saved-project = $(.current-project) ;
@@ -810,6 +824,7 @@
# This module defines rules common to all projects.
+#
module project-rules
{
rule using ( toolset-module : * )
@@ -926,8 +941,8 @@
# child Jamfile.
#
rule constant (
- name # Variable name of the constant.
- : value + # Value of the constant.
+ name # Variable name of the constant.
+ : value + # Value of the constant.
)
{
import project ;
@@ -938,9 +953,10 @@
# Declare and set a project global constant, whose value is a path. The path
# is adjusted to be relative to the invocation directory. The given value
# path is taken to be either absolute, or relative to this project root.
+ #
rule path-constant (
- name # Variable name of the constant.
- : value + # Value of the constant.
+ name # Variable name of the constant.
+ : value + # Value of the constant.
)
{
import project ;
@@ -979,8 +995,8 @@
rule glob ( wildcards + : excludes * )
{
import project ;
- return [ project.glob-internal [ project.current ]
- : $(wildcards) : $(excludes) : glob ] ;
+ return [ project.glob-internal [ project.current ] : $(wildcards) :
+ $(excludes) : glob ] ;
}
rule glob-tree ( wildcards + : excludes * )
@@ -1015,9 +1031,3 @@
}
}
}
-
-
-local rule __test__ ( )
-{
- import assert ;
-}
Modified: branches/release/tools/build/v2/build/property-set.jam
==============================================================================
--- branches/release/tools/build/v2/build/property-set.jam (original)
+++ branches/release/tools/build/v2/build/property-set.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -9,22 +9,23 @@
import sequence ;
import set ;
+
# Class for storing a set of properties.
-# - there's 1<->1 correspondence between identity and value. No two instances of
-# the class are equal. To maintain this property, the 'property-set.create'
-# rule should be used to create new instances. Instances are immutable.
#
-# - each property is classified with regard to it's effect on build results.
-# Incidental properties have no effect on build results, from Boost.Build's
-# point of view. Others are either free, or non-free, which we call 'base'.
-# Each property belongs to exactly one of those categories and it's possible
-# to get list of properties in each category.
+# There is 1<->1 correspondence between identity and value. No two instances
+# of the class are equal. To maintain this property, the 'property-set.create'
+# rule should be used to create new instances. Instances are immutable.
+#
+# Each property is classified with regard to its effect on build results.
+# Incidental properties have no effect on build results, from Boost.Build's
+# point of view. Others are either free, or non-free and we refer to non-free
+# ones as 'base'. Each property belongs to exactly one of those categories.
#
-# In addition, it's possible to get a list of properties with a specific
-# attribute.
+# It is possible to get a list of properties belonging to each category as
+# well as a list of properties with a specific attribute.
#
-# - several operations, like and refine and as-path are provided. They all use
-# caching whenever possible.
+# Several operations, like and refine and as-path are provided. They all use
+# caching whenever possible.
#
class property-set
{
@@ -92,6 +93,7 @@
}
# Returns Jam list of stored properties.
+ #
rule raw ( )
{
return $(self.raw) ;
@@ -103,18 +105,21 @@
}
# Returns properties that are neither incidental nor free.
+ #
rule base ( )
{
return $(self.base) ;
}
- # Returns free properties which are not dependency properties.
+ # Returns free properties which are not incidental.
+ #
rule free ( )
{
return $(self.free) ;
}
# Returns dependency properties.
+ #
rule dependency ( )
{
return $(self.dependency) ;
@@ -136,6 +141,7 @@
}
# Returns incidental properties.
+ #
rule incidental ( )
{
return $(self.incidental) ;
@@ -239,6 +245,7 @@
# Returns a list of
# - the computed path
# - if the path is relative to the build directory, a value of 'true'.
+ #
rule target-path ( )
{
if ! $(self.target-path)
@@ -318,6 +325,7 @@
}
# Returns all values of 'feature'.
+ #
rule get ( feature )
{
if ! $(self.map-built)
@@ -338,6 +346,7 @@
# Creates a new 'property-set' instance for the given raw properties or returns
# an already existing ones.
+#
rule create ( raw-properties * )
{
raw-properties = [ sequence.unique
@@ -356,6 +365,7 @@
# Creates a new 'property-set' instance after checking that all properties are
# valid and converting incidental properties into gristed form.
+#
rule create-with-validation ( raw-properties * )
{
property.validate $(raw-properties) ;
@@ -365,6 +375,7 @@
# Creates a property-set from the input given by the user, in the context of
# 'jamfile-module' at 'location'.
+#
rule create-from-user-input ( raw-properties * : jamfile-module location )
{
local specification = [ property.translate-paths $(raw-properties)
@@ -386,8 +397,8 @@
# bound.
# - location -- path to which path features are relative.
#
-rule refine-from-user-input ( parent-requirements : specification *
- : project-module : location )
+rule refine-from-user-input ( parent-requirements : specification * :
+ project-module : location )
{
if ! $(specification)
{
@@ -434,6 +445,7 @@
# Returns a property-set with an empty set of properties.
+#
rule empty ( )
{
if ! $(.empty)
Modified: branches/release/tools/build/v2/build/property.jam
==============================================================================
--- branches/release/tools/build/v2/build/property.jam (original)
+++ branches/release/tools/build/v2/build/property.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -18,6 +18,7 @@
# Refines 'properties' by overriding any non-free and non-conditional properties
# for which a different value is specified in 'requirements'. Returns the
# resulting list of properties.
+#
rule refine ( properties * : requirements * )
{
local result ;
@@ -27,7 +28,7 @@
# them so that we can handle 'properties'.
for local r in $(requirements)
{
- # Don't consider conditional requirements.
+ # Do not consider conditional requirements.
if ! [ MATCH (:) : $(r:G=) ]
{
# Note: cannot use a local variable here, so use an ugly name.
@@ -88,6 +89,7 @@
# Removes all conditional properties whose conditions are not met. For those
# with met conditions, removes the condition. Properties in conditions are
# looked up in 'context'.
+#
rule evaluate-conditionals-in-context ( properties * : context * )
{
local base ;
@@ -147,15 +149,17 @@
# passing 'true' as the second parameter.
e += [ feature.expand-subfeatures $(c) : true ] ;
}
-
if $(e) = $(condition)
{
+ # (todo)
+ # This is just an optimization and possibly a premature one at
+ # that.
+ # (todo) (12.07.2008.) (Jurko)
result += $(p) ;
}
else
{
- local individual-subfeatures = [ set.difference $(e) : $(condition) ] ;
- result += $(individual-subfeatures:J=,):$(value) ;
+ result += $(e:J=,):$(value) ;
}
}
}
@@ -165,6 +169,7 @@
# Helper for as-path, below. Orders properties with the implicit ones first, and
# within the two sections in alphabetical order of feature name.
+#
local rule path-order ( x y )
{
if $(y:G) && ! $(x:G)
@@ -219,16 +224,17 @@
# Returns a path representing the given expanded property set.
+#
rule as-path ( properties * )
{
local entry = .result.$(properties:J=-) ;
if ! $($(entry))
{
- # trim redundancy
+ # Trim redundancy.
properties = [ feature.minimize $(properties) ] ;
- # sort according to path-order
+ # Sort according to path-order.
properties = [ sequence.insertion-sort $(properties) : path-order ] ;
local components ;
@@ -250,6 +256,7 @@
# Exit with error if property is not valid.
+#
local rule validate1 ( property )
{
local msg ;
@@ -307,6 +314,7 @@
# Expands any implicit property values in the given property 'specification' so
# they explicitly state their feature.
+#
rule make ( specification * )
{
local result ;
@@ -332,6 +340,7 @@
# Returns a property set containing all the elements in 'properties' that do not
# have their attributes listed in 'attributes'.
+#
rule remove ( attributes + : properties * )
{
local result ;
@@ -346,8 +355,9 @@
}
-# Returns a property set containig all the elements in 'properties' that have
+# Returns a property set containing all the elements in 'properties' that have
# their attributes listed in 'attributes'.
+#
rule take ( attributes + : properties * )
{
local result ;
@@ -363,6 +373,7 @@
# Selects properties corresponding to any of the given features.
+#
rule select ( features * : properties * )
{
local result ;
@@ -384,6 +395,7 @@
# Returns a modified version of properties with all values of the given feature
# replaced by the given value. If 'value' is empty the feature will be removed.
+#
rule change ( properties * : feature value ? )
{
local result ;
@@ -406,6 +418,7 @@
# property. E.g. <variant>debug,<toolset>gcc:<inlining>full will become
# <variant>debug,<toolset>gcc <inlining>full. Otherwise, returns an empty
# string.
+#
rule split-conditional ( property )
{
local m = [ MATCH "(.+):<(.+)" : $(property) ] ;
@@ -419,6 +432,7 @@
# Interpret all path properties in 'properties' as relative to 'path'. The
# property values are assumed to be in system-specific form, and will be
# translated into normalized form.
+#
rule translate-paths ( properties * : path )
{
local result ;
@@ -456,6 +470,7 @@
# in 'context-module'. Such rules can be either local to the module or global.
# Converts such values into 'indirect-rule' format (see indirect.jam), so they
# can be called from other modules.
+#
rule translate-indirect ( specification * : context-module )
{
local result ;
@@ -497,7 +512,8 @@
}
-# Class which maintains a property set -> string mapping.
+# Class maintaining a property set -> string mapping.
+#
class property-map
{
import errors ;
@@ -509,7 +525,8 @@
self.next-flag = 1 ;
}
- # Associate 'value' with 'properties'
+ # Associate 'value' with 'properties'.
+ #
rule insert ( properties + : value )
{
self.all-flags += $(self.next-flag) ;
@@ -521,7 +538,8 @@
# Returns the value associated with 'properties' or any subset of it. If
# more than one subset has a value assigned to it, returns the value for the
- # longest subset, if it's unique.
+ # longest subset, if it is unique.
+ #
rule find ( properties + )
{
return [ find-replace $(properties) ] ;
@@ -529,9 +547,10 @@
# Returns the value associated with 'properties'. If 'value' parameter is
# given, replaces the found value.
+ #
rule find-replace ( properties + : value ? )
{
- # First find all matches
+ # First find all matches.
local matches ;
local match-ranks ;
for local i in $(self.all-flags)
@@ -558,7 +577,7 @@
}
-local rule __test__ ( )
+rule __test__ ( )
{
import assert ;
import "class" : new ;
@@ -591,24 +610,24 @@
assert.true path-order $(test-space) <optimization>on <rtti>on ;
assert.false path-order $(test-space) <rtti>on <optimization>on ;
- assert.result-equal <toolset>gcc <rtti>off <define>FOO
+ assert.result-set-equal <toolset>gcc <rtti>off <define>FOO
: refine <toolset>gcc <rtti>off
: <define>FOO
: $(test-space) ;
- assert.result-equal <toolset>gcc <optimization>on
+ assert.result-set-equal <toolset>gcc <optimization>on
: refine <toolset>gcc <optimization>off
: <optimization>on
: $(test-space) ;
- assert.result-equal <toolset>gcc <rtti>off
+ assert.result-set-equal <toolset>gcc <rtti>off
: refine <toolset>gcc : <rtti>off : $(test-space) ;
- assert.result-equal <toolset>gcc <rtti>off <rtti>off:<define>FOO
+ assert.result-set-equal <toolset>gcc <rtti>off <rtti>off:<define>FOO
: refine <toolset>gcc : <rtti>off <rtti>off:<define>FOO
: $(test-space) ;
- assert.result-equal <toolset>gcc:<define>foo <toolset>gcc:<define>bar
+ assert.result-set-equal <toolset>gcc:<define>foo <toolset>gcc:<define>bar
: refine <toolset>gcc:<define>foo : <toolset>gcc:<define>bar
: $(test-space) ;
@@ -646,19 +665,19 @@
validate value : $(test-space) ;
catch "value" is not a value of an implicit feature ;
- assert.result-equal <rtti>on
+ assert.result-set-equal <rtti>on
: remove free implicit : <toolset>gcc <define>foo <rtti>on : $(test-space) ;
- assert.result-equal <include>a
+ assert.result-set-equal <include>a
: select include : <include>a <toolset>gcc ;
- assert.result-equal <include>a
+ assert.result-set-equal <include>a
: select include bar : <include>a <toolset>gcc ;
- assert.result-equal <include>a <toolset>gcc
+ assert.result-set-equal <include>a <toolset>gcc
: select include <bar> <toolset> : <include>a <toolset>gcc ;
- assert.result-equal <toolset>kylix <include>a
+ assert.result-set-equal <toolset>kylix <include>a
: change <toolset>gcc <include>a : <toolset> kylix ;
pm = [ new property-map ] ;
@@ -681,7 +700,7 @@
assert.result : split-conditional <define>FOO=A::B ;
# Test conditional feature.
- assert.result-equal <toolset>gcc,<toolset-gcc:version>3.0 <define>FOO
+ assert.result-set-equal <toolset>gcc,<toolset-gcc:version>3.0 <define>FOO
: split-conditional <toolset>gcc,<toolset-gcc:version>3.0:<define>FOO ;
feature.finish-test property-test-temp ;
Modified: branches/release/tools/build/v2/build/scanner.jam
==============================================================================
--- branches/release/tools/build/v2/build/scanner.jam (original)
+++ branches/release/tools/build/v2/build/scanner.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -28,6 +28,7 @@
import "class" : new ;
import property virtual-target property-set ;
+import errors : error ;
# Base scanner class.
class scanner
Modified: branches/release/tools/build/v2/build/targets.jam
==============================================================================
--- branches/release/tools/build/v2/build/targets.jam (original)
+++ branches/release/tools/build/v2/build/targets.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -5,29 +5,28 @@
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
-# Supports 'abstract' targets, which are targets explicitly defined in a
-# Jamfile.
+# Supports 'abstract' targets, which are targets explicitly defined in a
+# Jamfile.
#
-# Abstract targets are represented by classes derived from 'abstract-target'
-# class. The first abstract target is 'project-target', which is created for
-# 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 definitions for a main target, for example to have different lists
-# of sources for different platforms. So, main targets keep a list of
-# alternatives.
-#
-# Each alternative is an instance of 'abstract-target'. When a main target
-# subvariant is defined by some rule, that rule will decide what class to use,
-# create an instance of that class and add it to the list of alternatives for
-# the main target.
-#
-# Rules supplied by the build system will use only targets derived from
-# 'basic-target' class, which will provide some default behaviour. There will
-# be different classes derived from it such as 'make-target', created by the
-# 'make' rule, and 'typed-target', created by rules such as 'exe' and 'lib'.
+# Abstract targets are represented by classes derived from 'abstract-target'
+# class. The first abstract target is 'project-target', which is created for
+# 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
+# definitions for a main target, for example to have different lists of sources
+# for different platforms. So, main targets keep a list of alternatives.
+#
+# Each alternative is an instance of 'abstract-target'. When a main target
+# subvariant is defined by some rule, that rule will decide what class to use,
+# create an instance of that class and add it to the list of alternatives for
+# the main target.
+#
+# Rules supplied by the build system will use only targets derived from
+# 'basic-target' class, which will provide some default behaviour. There will be
+# different classes derived from it such as 'make-target', created by the 'make'
+# rule, and 'typed-target', created by rules such as 'exe' and 'lib'.
#
# +------------------------+
@@ -80,7 +79,9 @@
import set ;
import toolset ;
+
# Base class for all abstract targets.
+#
class abstract-target
{
import project ;
@@ -135,6 +136,7 @@
# - a list of produced virtual targets, which may be empty.
# If 'property-set' is empty, performs the default build of this target, in
# a way specific to the derived class.
+ #
rule generate ( property-set )
{
errors.error "method should be defined in derived classes" ;
@@ -181,6 +183,7 @@
# that time, alternatives can also be renamed to account for inline targets.
# - The first time 'main-target' or 'has-main-target' rule is called, all
# alternatives are enumerated and main targets are created.
+#
class project-target : abstract-target
{
import project ;
@@ -211,6 +214,7 @@
# This is needed only by the 'make' rule. Need to find the way to make
# 'make' work without this method.
+ #
rule project-module ( )
{
return $(self.project-module) ;
@@ -238,6 +242,7 @@
}
# Generates all possible targets contained in this project.
+ #
rule generate ( property-set * )
{
if [ modules.peek : .debug-building ]
@@ -261,6 +266,7 @@
# Computes and returns a list of abstract-target instances which must be
# built when this project is built.
+ #
rule targets-to-build ( )
{
local result ;
@@ -291,6 +297,7 @@
# Add 'target' to the list of targets in this project that should be build
# only by explicit request
+ #
rule mark-target-as-explicit ( target-name )
{
# Record the name of the target, not instance, since this
@@ -299,6 +306,7 @@
}
# Add new target alternative
+ #
rule add-alternative ( target-instance )
{
if $(self.built-main-targets)
@@ -310,6 +318,7 @@
}
# Returns a 'main-target' class instance corresponding to the 'name'.
+ #
rule main-target ( name )
{
if ! $(self.built-main-targets)
@@ -321,6 +330,7 @@
}
# Tells if a main target with the specified name exists.
+ #
rule has-main-target ( name )
{
if ! $(self.built-main-targets)
@@ -334,8 +344,9 @@
}
}
- # Find and return the target with the specified id, treated
- # relative to self.
+ # Find and return the target with the specified id, treated relative to
+ # self.
+ #
rule find-really ( id )
{
local result ;
@@ -452,6 +463,7 @@
}
# Accessor, add a constant.
+ #
rule add-constant (
name # Variable name of the constant.
: value + # Value of the constant.
@@ -495,7 +507,7 @@
# Import rules from parent.
local this-module = [ project-module ] ;
local parent-module = [ $(parent).project-module ] ;
- # Don't import rules coming from 'project-rules' as they must be
+ # Do not import rules coming from 'project-rules' as they must be
# imported localized.
local user-rules = [ set.difference
[ RULENAMES $(parent-module) ] :
@@ -506,7 +518,8 @@
}
-# Helper rules to detect cycles in main target references
+# Helper rules to detect cycles in main target references.
+#
local rule start-building ( main-target-instance )
{
if $(main-target-instance) in $(.targets-being-built)
@@ -532,6 +545,7 @@
# A named top-level target in Jamfile.
+#
class main-target : abstract-target
{
import assert ;
@@ -568,6 +582,7 @@
# Returns the best viable alternative for this property-set. See the
# documentation for selection rules.
+ #
local rule select-alternatives ( property-set debug ? )
{
# When selecting alternatives we have to consider defaults, for example:
@@ -697,8 +712,9 @@
# Select an alternative for this main target, by finding all alternatives
# which requirements are satisfied by 'properties' and picking the one with
- # longest requirements set. Returns the result of calling 'generate' on that
- # alternative.
+ # the longest requirements set. Returns the result of calling 'generate' on
+ # that alternative.
+ #
rule generate ( property-set )
{
start-building $(__name__) ;
@@ -726,7 +742,8 @@
# Generates the main target with the given property set and returns a list
# which first element is property-set object containing usage-requirements
# of generated target and with generated virtual target in other elements.
- # It's possible that no targets are generated.
+ # It is possible that no targets are generated.
+ #
local rule generate-really ( property-set )
{
local best-alternatives = [ select-alternatives $(property-set) ] ;
@@ -757,6 +774,7 @@
# Abstract target which refers to a source file. This is an artificial entity
# allowing sources to a target to be represented using a list of abstract target
# instances.
+#
class file-reference : abstract-target
{
import virtual-target ;
@@ -811,9 +829,10 @@
# Given a target-reference, made in context of 'project', returns the
# abstract-target instance that is referred to, as well as properties explicitly
# specified for this reference.
+#
rule resolve-reference ( target-reference : project )
{
- # Separate target name from properties override
+ # Separate target name from properties override.
local split = [ MATCH "^([^<]*)(/(<.*))?$" : $(target-reference) ] ;
local id = $(split[1]) ;
local sproperties = ;
@@ -823,7 +842,7 @@
sproperties = [ feature.expand-composites $(sproperties) ] ;
}
- # Find the target
+ # Find the target.
local target = [ $(project).find $(id) ] ;
return $(target) [ property-set.create $(sproperties) ] ;
@@ -834,6 +853,7 @@
# both to a main target or to a file. Returns a list consisting of
# - usage requirements
# - generated virtual targets, if any
+#
rule generate-from-reference (
target-reference # Target reference.
: project # Project where the reference is made.
@@ -860,15 +880,23 @@
# Given a build request and requirements, return properties common to dependency
-# build request and target build properties.
+# build request and target requirements.
+#
+# TODO: Document exactly what 'common properties' are, whether they should
+# include default property values, whether they should contain any conditional
+# properties or should those be already processed, etc. See whether there are
+# any differences between use cases with empty and non-empty build-request as
+# well as with requirements containing and those not containing any non-free
+# features.
+#
rule common-properties ( build-request requirements )
{
# For optimization, we add free requirements directly, without using a
- # complex algorithm. This gives the complex algorithm better chance of
+ # complex algorithm. This gives the complex algorithm a better chance of
# caching results.
local free = [ $(requirements).free ] ;
- local non-free = [ property-set.create
- [ $(requirements).base ] [ $(requirements).incidental ] ] ;
+ local non-free = [ property-set.create [ $(requirements).base ]
+ [ $(requirements).incidental ] ] ;
local key = .rp.$(build-request)-$(non-free) ;
if ! $($(key))
@@ -879,7 +907,7 @@
}
-# Given 'context' -- a set of already present properties, and 'requirements',
+# Given a 'context' -- a set of already present properties, and 'requirements',
# decide which extra properties should be applied to 'context'. For conditional
# requirements, this means evaluating condition. For indirect conditional
# requirements, this means calling a rule. Ordinary requirements are always
@@ -891,15 +919,16 @@
#
# If 'what' is 'refined' returns context refined with new requirements. If
# 'what' is 'added' returns just the requirements to be applied.
+#
rule evaluate-requirements ( requirements : context : what )
{
- # Apply non-conditional requirements. It's possible that further conditional
- # requirement change a value set by non-conditional requirements. For
- # example:
+ # Apply non-conditional requirements. It is possible that further
+ # conditional requirement change a value set by non-conditional
+ # requirements. For example:
#
# exe a : a.cpp : <threading>single <toolset>foo:<threading>multi ;
#
- # I'm not sure if this should be an error, or not, especially given that
+ # I am not sure if this should be an error, or not, especially given that
#
# <threading>single
#
@@ -910,15 +939,15 @@
local raw = [ $(context).raw ] ;
raw = [ property.refine $(raw) : $(unconditional) ] ;
- # We've collected properties that surely must be present in common
+ # We have collected properties that surely must be present in common
# properties. We now try to figure out what other properties should be added
# in order to satisfy rules (4)-(6) from the docs.
local conditionals = [ $(requirements).conditional ] ;
# The 'count' variable has one element for each conditional feature and for
- # each occurence of '<indirect-conditional>' feature. It's used as a loop
+ # each occurence of '<indirect-conditional>' feature. It is used as a loop
# counter: for each iteration of the loop before we remove one element and
- # the property set should stabilize before we're done. It's assumed that
+ # the property set should stabilize before we are done. It is assumed that
# #conditionals iterations should be enough for properties to propagate
# along conditions in any direction.
local count = $(conditionals)
@@ -929,9 +958,9 @@
local current = $(raw) ;
- # It's assumed that ordinary conditional requirements can't add
- # <indirect-conditional> properties, and that rules referred by
- # <indirect-conditional> properties can't add new <indirect-conditional>
+ # It is assumed that ordinary conditional requirements can not add
+ # <indirect-conditional> properties, and that rules referred to by
+ # <indirect-conditional> properties can not add new <indirect-conditional>
# properties. So the list of indirect conditionals does not change.
local indirect = [ $(requirements).get <conditional> ] ;
indirect = [ MATCH @(.*) : $(indirect) ] ;
@@ -957,9 +986,9 @@
}
else
{
- # Oops, results of evaluation of conditionals has changed. Also
- # 'current' contains leftover from previous evaluation. Recompute
- # 'current' using initial properties and conditional requirements.
+ # Oops, conditional evaluation results have changed. Also 'current'
+ # contains leftovers from a previous evaluation. Recompute 'current'
+ # using initial properties and conditional requirements.
added-requirements = $(e) ;
current = [ property.refine $(raw) : [ feature.expand $(e) ] ] ;
}
@@ -967,7 +996,7 @@
}
if ! $(ok)
{
- errors.error "Can't evaluate conditional properties " $(conditionals) ;
+ errors.error "Can not evaluate conditional properties " $(conditionals) ;
}
if $(what) = added
@@ -989,24 +1018,25 @@
{
# This guarantees that default properties are present in the result, unless
# they are overriden by some requirement. FIXME: There is possibility that
- # we've added <foo>bar, which is composite and expands to <foo2>bar2, but
- # default value of <foo2> is not bar2, in which case it's not clear what to
+ # we have added <foo>bar, which is composite and expands to <foo2>bar2, but
+ # default value of <foo2> is not bar2, in which case it is not clear what to
# do.
#
build-request = [ $(build-request).add-defaults ] ;
# Features added by 'add-default' can be composite and expand to features
# without default values -- so they are not added yet. It could be clearer/
- # /faster to expand only newly added properties but that's not critical.
+ # /faster to expand only newly added properties but that is not critical.
build-request = [ $(build-request).expand ] ;
- return [ evaluate-requirements $(requirements)
- : $(build-request) : refined ] ;
+ return [ evaluate-requirements $(requirements) : $(build-request) :
+ refined ] ;
}
# Implements the most standard way of constructing main target alternative from
# sources. Allows sources to be either file or other main target and handles
# generation of those dependency targets.
+#
class basic-target : abstract-target
{
import build-request ;
@@ -1051,9 +1081,11 @@
# Returns the list of abstract-targets which are used as sources. The extra
# properties specified for sources are not represented. The only user for
# this rule at the moment is the "--dump-tests" feature of the test system.
+ #
rule sources ( )
{
- if ! $(self.source-targets) {
+ if ! $(self.source-targets)
+ {
for local s in $(self.sources)
{
self.source-targets +=
@@ -1075,16 +1107,16 @@
# Returns the alternative condition for this alternative, if the condition
# is satisfied by 'property-set'.
+ #
rule match ( property-set debug ? )
{
- # The condition is composed of all base non-conditional properties. It's
- # not clear if we should expand 'self.requirements' or not. For one
+ # The condition is composed of all base non-conditional properties. It
+ # is not clear if we should expand 'self.requirements' or not. For one
# thing, it would be nice to be able to put
# <toolset>msvc-6.0
- # in requirements.
- # On the other hand, if we have <variant>release in condition it does
- # not make sense to require <optimization>full to be in build request
- # just to select this variant.
+ # in requirements. On the other hand, if we have <variant>release as a
+ # condition it does not make sense to require <optimization>full to be
+ # in the build request just to select this variant.
local bcondition = [ $(self.requirements).base ] ;
local ccondition = [ $(self.requirements).conditional ] ;
local condition = [ set.difference $(bcondition) : $(ccondition) ] ;
@@ -1116,6 +1148,7 @@
#
# The results are added to the variable called 'result-var'. Usage
# requirements are added to the variable called 'usage-requirements-var'.
+ #
rule generate-dependencies ( dependencies * : property-set
: result-var usage-requirements-var )
{
@@ -1124,9 +1157,8 @@
local grist = $(dependency:G) ;
local id = $(dependency:G=) ;
- local result =
- [ targets.generate-from-reference $(id) : $(self.project)
- : $(property-set) ] ;
+ local result = [ targets.generate-from-reference $(id) :
+ $(self.project) : $(property-set) ] ;
$(result-var) += $(result[2-]:G=$(grist)) ;
$(usage-requirements-var) += [ $(result[1]).raw ] ;
@@ -1135,6 +1167,7 @@
# Determines final build properties, generates sources, and calls
# 'construct'. This method should not be overridden.
+ #
rule generate ( property-set )
{
if [ modules.peek : .debug-building ]
@@ -1143,7 +1176,7 @@
local fn = [ full-name ] ;
ECHO [ targets.indent ] "Building target '$(fn)'" ;
targets.increase-indent ;
- ECHO [ targets.indent ] "Build request: " [ $(property-set).raw ] ;
+ ECHO [ targets.indent ] "Build request: " $(property-set) [ $(property-set).raw ] ;
local cf = [ build-system.command-line-free-features ] ;
ECHO [ targets.indent ] "Command line free features: " [ $(cf).raw ] ;
ECHO [ targets.indent ] "Target requirements: " [ $(self.requirements).raw ] ;
@@ -1151,7 +1184,7 @@
if ! $(self.generated.$(property-set))
{
- # Apply free features form the command line. If user said
+ # Apply free features from the command line. If user said
# define=FOO
# he most likely wants this define to be set for all compiles.
property-set = [ $(property-set).refine
@@ -1162,7 +1195,7 @@
if [ modules.peek : .debug-building ]
{
ECHO ;
- ECHO [ targets.indent ] "Common properties:" [ $(rproperties).raw ] ;
+ ECHO [ targets.indent ] "Common properties: " [ $(rproperties).raw ] ;
}
if $(rproperties[1]) != "@error" && [ $(rproperties).get <build> ] != no
@@ -1171,18 +1204,17 @@
local properties = [ $(rproperties).non-dependency ] ;
local usage-requirements ;
- generate-dependencies [ $(rproperties).dependency ]
- : $(rproperties)
- : properties usage-requirements ;
+ generate-dependencies [ $(rproperties).dependency ] :
+ $(rproperties) : properties usage-requirements ;
- generate-dependencies $(self.sources) : $(rproperties)
- : source-targets usage-requirements ;
+ generate-dependencies $(self.sources) : $(rproperties) :
+ source-targets usage-requirements ;
if [ modules.peek : .debug-building ]
{
ECHO ;
- ECHO [ targets.indent ]
- "Usage requirements for $(self.name) are " $(usage-requirements) ;
+ ECHO [ targets.indent ] "Usage requirements for"
+ $(self.name)": " $(usage-requirements) ;
}
rproperties = [ property-set.create $(properties)
@@ -1191,8 +1223,8 @@
if [ modules.peek : .debug-building ]
{
- ECHO [ targets.indent ]
- "Build properties: " [ $(rproperties).raw ] ;
+ ECHO [ targets.indent ] "Build properties: "
+ [ $(rproperties).raw ] ;
}
local extra = [ $(rproperties).get <source> ] ;
@@ -1201,9 +1233,8 @@
# libraries having the same <library> usage requirement.
source-targets = [ sequence.unique $(source-targets) ] ;
- local result =
- [ construct $(self.name) :
- $(source-targets) : $(rproperties) ] ;
+ local result = [ construct $(self.name) : $(source-targets) :
+ $(rproperties) ] ;
if $(result)
{
@@ -1221,9 +1252,8 @@
$(s).set-usage-requirements $(ur) ;
if [ modules.peek : .debug-building ]
{
- ECHO [ targets.indent ]
- "Usage requirements from $(self.name) are "
- [ $(ur).raw ] ;
+ ECHO [ targets.indent ] "Usage requirements from"
+ $(self.name)": " [ $(ur).raw ] ;
}
self.generated.$(property-set) = $(ur) $(result) ;
@@ -1233,24 +1263,34 @@
{
if $(rproperties[1]) = "@error"
{
- ECHO [ targets.indent ]
- "Skipping build of: " [ full-name ] " cannot compute common properties" ;
+ ECHO [ targets.indent ] "Skipping build of:" [ full-name ]
+ "cannot compute common properties" ;
}
else if [ $(rproperties).get <build> ] = no
{
- ECHO [ targets.indent ]
- "Skipping build of: " [ full-name ] " <build>no in common properties" ;
+ ECHO [ targets.indent ] "Skipping build of: " [ full-name ]
+ " <build>no in common properties" ;
}
else
{
- ECHO [ targets.indent ] "Skipping build of: " [ full-name ] " unknown reason" ;
+ ECHO [ targets.indent ] "Skipping build of: " [ full-name ]
+ " unknown reason" ;
}
- # We're here either because there's been an error computing
- # properties, or there's <build>no in properties. In the latter
- # case we don't want any diagnostic. In the former case, we need
- # diagnostics. FIXME
- self.generated.$(property-set) = $(rproperties) ;
+ # We are here either because there has been an error computing
+ # properties or there is <build>no in properties. In the latter
+ # case we do not want any diagnostic. In the former case, we
+ # need diagnostics. FIXME
+
+ # If this target fails to build, add <build>no to properties to
+ # cause any parent target to fail to build. Except that it
+ # - does not work now, since we check for <build>no only in
+ # common properties, but not in properties that came from
+ # dependencies
+ # - it is not clear if that is a good idea anyway. The alias
+ # target, for example, should not fail to build if a
+ # dependency fails.
+ self.generated.$(property-set) = [ property-set.create <build>no ] ;
}
}
else
@@ -1258,6 +1298,12 @@
if [ modules.peek : .debug-building ]
{
ECHO [ targets.indent ] "Already built" ;
+ local ur = $(self.generated.$(property-set)) ;
+ ur = $(ur[0]) ;
+ targets.increase-indent ;
+ ECHO [ targets.indent ] "Usage requirements from"
+ $(self.name)": " [ $(ur).raw ] ;
+ targets.decrease-indent ;
}
}
@@ -1266,7 +1312,8 @@
}
# Given the set of generated targets, and refined build properties,
- # determines and sets appripriate usage requirements on those targets.
+ # determines and sets appropriate usage requirements on those targets.
+ #
rule compute-usage-requirements ( subvariant )
{
local rproperties = [ $(subvariant).build-properties ] ;
@@ -1282,7 +1329,7 @@
local result = [ property-set.create
[ $(xusage-requirements).non-dependency ] $(extra) ] ;
- # Propagate usage requirements we've got from sources, except for the
+ # Propagate usage requirements we got from sources, except for the
# <pch-header> and <pch-file> features.
#
# That feature specifies which pch file to use, and should apply only to
@@ -1298,6 +1345,13 @@
# Essentially, when those two features are in usage requirements, they
# are propagated only to direct dependents. We might need a more general
# mechanism, but for now, only those two features are special.
+ #
+ # TODO - Actually there are more possible candidates like for instance
+ # when listing static library X as a source for another static library.
+ # Then static library X will be added as a <source> property to the
+ # second library's usage requirements but those requirements should last
+ # only up to the first executable or shared library that actually links
+ # to it.
local raw = [ $(subvariant).sources-usage-requirements ] ;
raw = [ $(raw).raw ] ;
raw = [ property.change $(raw) : <pch-header> ] ;
@@ -1309,9 +1363,9 @@
# 'root-targets' - virtual targets to be returned to dependants
# 'all-targets' - virtual targets created while building this main target
# 'build-request' - property-set instance with requested build properties
- local rule create-subvariant ( root-targets *
- : all-targets * : build-request : sources * : rproperties
- : usage-requirements )
+ #
+ local rule create-subvariant ( root-targets * : all-targets * :
+ build-request : sources * : rproperties : usage-requirements )
{
for local e in $(root-targets)
{
@@ -1320,8 +1374,8 @@
# Process all virtual targets that will be created if this main target
# is created.
- local s = [ new subvariant $(__name__) : $(build-request) : $(sources)
- : $(rproperties) : $(usage-requirements) : $(all-targets) ] ;
+ local s = [ new subvariant $(__name__) : $(build-request) : $(sources) :
+ $(rproperties) : $(usage-requirements) : $(all-targets) ] ;
for local v in $(all-targets)
{
if ! [ $(v).creating-subvariant ]
@@ -1333,8 +1387,9 @@
}
# Constructs virtual targets for this abstract target and the dependency
- # graph. Returns the list of virtual targets. Should be overriden in derived
- # classes.
+ # graph. Returns a usage-requirements property-set and a list of virtual
+ # targets. Should be overriden in derived classes.
+ #
rule construct ( name : source-targets * : properties * )
{
errors.error "method should be defined in derived classes" ;
@@ -1423,6 +1478,7 @@
# Returns the requirements to use when declaring a main target, obtained by
# translating all specified property paths and refining project requirements
# with the ones specified for the target.
+#
rule main-target-requirements (
specification * # Properties explicitly specified for the main target.
: project # Project where the main target is to be declared.
@@ -1444,6 +1500,7 @@
# Returns the usage requirements to use when declaring a main target, which are
# obtained by translating all specified property paths and adding project's
# usage requirements.
+#
rule main-target-usage-requirements (
specification * # Use-properties explicitly specified for a main target.
: project # Project where the main target is to be declared.
@@ -1466,6 +1523,7 @@
# Return the default build value to use when declaring a main target, which is
# obtained by using the specified value if not empty and parent's default build
# attribute otherwise.
+#
rule main-target-default-build (
specification * # Default build explicitly specified for a main target.
: project # Project where the main target is to be declared.
@@ -1485,6 +1543,7 @@
# Registers the specified target as a main target alternative and returns it.
+#
rule main-target-alternative ( target )
{
local ptarget = [ $(target).project ] ;
@@ -1496,8 +1555,9 @@
# Creates a typed-target with the specified properties. The 'name', 'sources',
# 'requirements', 'default-build' and 'usage-requirements' are assumed to be in
# the form specified by the user in Jamfile corresponding to 'project'.
-rule create-typed-target ( type : project : name : sources * : requirements *
- : default-build * : usage-requirements * )
+#
+rule create-typed-target ( type : project : name : sources * : requirements * :
+ default-build * : usage-requirements * )
{
return [
targets.main-target-alternative
Modified: branches/release/tools/build/v2/build/toolset.jam
==============================================================================
--- branches/release/tools/build/v2/build/toolset.jam (original)
+++ branches/release/tools/build/v2/build/toolset.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -135,7 +135,6 @@
}
}
-
if $(condition) && ! $(condition:G=) && ! $(hack-hack)
{
# We have condition in the form '<feature>', that is, without value.
@@ -153,8 +152,7 @@
condition = [ normalize-condition $(condition) ] ;
}
- add-flag $(rule-or-module) : $(variable-name)
- : $(condition) : $(values) ;
+ add-flag $(rule-or-module) : $(variable-name) : $(condition) : $(values) ;
}
@@ -327,8 +325,8 @@
local settings = $(.stv.$(key)) ;
if ! $(settings)
{
- settings = [
- set-target-variables-aux $(rule-or-module) : $(property-set) ] ;
+ settings = [ set-target-variables-aux $(rule-or-module) :
+ $(property-set) ] ;
if ! $(settings)
{
@@ -486,7 +484,7 @@
}
-local rule __test__ ( )
+rule __test__ ( )
{
import assert ;
local p = <b>0 <c>1 <d>2 <e>3 <f>4 ;
Modified: branches/release/tools/build/v2/build/type.jam
==============================================================================
--- branches/release/tools/build/v2/build/type.jam (original)
+++ branches/release/tools/build/v2/build/type.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -18,8 +18,8 @@
# project -> project-root -> builtin -> type -> targets -> project
# import targets ;
-# The feature is optional so it would never get added implicitly. It's used only
-# for internal purposes and in all cases we want to use it explicitly.
+# The feature is optional so it would never get added implicitly. It is used
+# only for internal purposes and in all cases we want to use it explicitly.
feature.feature target-type : : composite optional ;
feature.feature main-target-type : : optional incidental ;
@@ -30,6 +30,7 @@
# of 'suffixes' here is a shortcut for separately calling the register-suffixes
# rule with the given suffixes and the set-generated-target-suffix rule with the
# first given suffix.
+#
rule register ( type : suffixes * : base-type ? )
{
# Type names cannot contain hyphens, because when used as feature-values
@@ -81,6 +82,7 @@
# Given a type, returns the name of the main target rule which creates targets
# of that type.
+#
rule type-to-rule-name ( type )
{
# Lowercase everything. Convert underscores to dashes.
@@ -91,6 +93,7 @@
# Given a main target rule name, returns the type for which it creates targets.
+#
rule type-from-rule-name ( rule-name )
{
return $(.main-target-type.$(rule-name)) ;
@@ -100,6 +103,7 @@
# Specifies that files with suffix from 'suffixes' be recognized as targets of
# type 'type'. Issues an error if a different type is already specified for any
# of the suffixes.
+#
rule register-suffixes ( suffixes + : type )
{
for local s in $(suffixes)
@@ -118,6 +122,7 @@
# Returns true iff type has been registered.
+#
rule registered ( type )
{
if $(type) in $(.types)
@@ -128,6 +133,7 @@
# Issues an error if 'type' is unknown.
+#
rule validate ( type )
{
if ! $(type) in $(.types)
@@ -138,6 +144,7 @@
# Sets a scanner class that will be used for this 'type'.
+#
rule set-scanner ( type : scanner )
{
if ! $(type) in $(.types)
@@ -149,6 +156,7 @@
# Returns a scanner instance appropriate to 'type' and 'properties'.
+#
rule get-scanner ( type : property-set )
{
if $(.scanner.$(type))
@@ -160,6 +168,7 @@
# Returns the given type and all of its base types in order of their distance
# from type.
+#
rule all-bases ( type )
{
local result = $(type) ;
@@ -184,6 +193,7 @@
# Returns true if 'type' has 'base' as its direct or indirect base.
+#
rule is-derived ( type base )
{
if $(base) in [ all-bases $(type) ]
@@ -194,6 +204,7 @@
# Returns true if 'type' is either derived from or is equal to 'base'.
+#
rule is-subtype ( type base )
{
if $(type) = $(base)
@@ -233,6 +244,7 @@
# Change the suffix previously registered for this type/properties combination.
# If suffix is not yet specified, sets it.
+#
rule change-generated-target-suffix ( type : properties * : suffix )
{
change-generated-target-ps suffix : $(type) : $(properties) : $(suffix) ;
@@ -241,6 +253,7 @@
# Returns the suffix used when generating a file of 'type' with the given
# properties.
+#
rule generated-target-suffix ( type : property-set )
{
return [ generated-target-ps suffix : $(type) : $(property-set) ] ;
@@ -255,6 +268,7 @@
# should be used.
#
# Usage example: library names use the "lib" prefix on unix.
+#
rule set-generated-target-prefix ( type : properties * : prefix )
{
set-generated-target-ps prefix : $(type) : $(properties) : $(prefix) ;
@@ -263,6 +277,7 @@
# Change the prefix previously registered for this type/properties combination.
# If prefix is not yet specified, sets it.
+#
rule change-generated-target-prefix ( type : properties * : prefix )
{
change-generated-target-ps prefix : $(type) : $(properties) : $(prefix) ;
@@ -299,6 +314,7 @@
# when generating a target of 'type' with the specified properties. Parameter
# 'ps' can be either "prefix" or "suffix". If no prefix/suffix is specified for
# 'type', returns prefix/suffix for base type, if any.
+#
local rule generated-target-ps-real ( ps : type : properties * )
{
local result ;
@@ -348,6 +364,7 @@
# Returns file type given it's name. If there are several dots in filename,
# tries each suffix. E.g. for name of "file.so.1.2" suffixes "2", "1", and "so"
# will be tried.
+#
rule type ( filename )
{
local type ;
@@ -365,6 +382,7 @@
# 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.
+#
rule main-target-rule ( name : sources * : requirements * : default-build *
: usage-requirements * )
{
Modified: branches/release/tools/build/v2/build/version.jam
==============================================================================
--- branches/release/tools/build/v2/build/version.jam (original)
+++ branches/release/tools/build/v2/build/version.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,7 +1,12 @@
# Copyright 2002, 2003, 2004, 2006 Vladimir Prus
+# Copyright 2008 Jurko Gospodnetic
# 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)
+import errors ;
+import numbers ;
+
+
rule boost-build ( )
{
return "V2 (Milestone 12)" ;
@@ -10,7 +15,7 @@
rule jam ( )
{
- local v = [ modules.peek : JAM_VERSION ] ;
+ local v = [ modules.peek : JAM_VERSION ] ;
return $(v:J=.) ;
}
@@ -20,3 +25,119 @@
ECHO "Boost.Build" [ boost-build ] ;
ECHO "Boost.Jam" [ jam ] ;
}
+
+
+# Utility rule for testing whether all elements in a sequence are equal to 0.
+#
+local rule is-all-zeroes ( sequence * )
+{
+ local result = "true" ;
+ for local e in $(sequence)
+ {
+ if $(e) != "0"
+ {
+ result = "" ;
+ }
+ }
+ return $(result) ;
+}
+
+
+# Returns "true" if the first version is less than the second one.
+#
+rule version-less ( lhs + : rhs + )
+{
+ numbers.check $(lhs) ;
+ numbers.check $(rhs) ;
+
+ local done ;
+ local result ;
+
+ while ! $(done) && $(lhs) && $(rhs)
+ {
+ if [ numbers.less $(lhs[1]) $(rhs[1]) ]
+ {
+ done = "true" ;
+ result = "true" ;
+ }
+ else if [ numbers.less $(rhs[1]) $(lhs[1]) ]
+ {
+ done = "true" ;
+ }
+ else
+ {
+ lhs = $(lhs[2-]) ;
+ rhs = $(rhs[2-]) ;
+ }
+ }
+ if ( ! $(done) && ! $(lhs) && ! [ is-all-zeroes $(rhs) ] )
+ {
+ result = "true" ;
+ }
+
+ return $(result) ;
+}
+
+
+# Returns "true" if the current JAM version version is at least the given
+# version.
+#
+rule check-jam-version ( version + )
+{
+ local version-tag = $(version:J=.) ;
+ if ! $(version-tag)
+ {
+ errors.error Invalid version specifier: : $(version:E="(undefined)") ;
+ }
+
+ if ! $(.jam-version-check.$(version-tag))-is-not-empty
+ {
+ local jam-version = [ modules.peek : JAM_VERSION ] ;
+ if ! $(jam-version)
+ {
+ errors.error "Unable to deduce Boost Jam version. Your Boost Jam"
+ "installation is most likely terribly outdated." ;
+ }
+ .jam-version-check.$(version-tag) = "true" ;
+ if [ version-less [ modules.peek : JAM_VERSION ] : $(version) ]
+ {
+ .jam-version-check.$(version-tag) = "" ;
+ }
+ }
+ return $(.jam-version-check.$(version-tag)) ;
+}
+
+
+rule __test__ ( )
+{
+ import assert ;
+
+ local jam-version = [ modules.peek : JAM_VERSION ] ;
+ local future-version = $(jam-version) ;
+ future-version += "1" ;
+
+ assert.true check-jam-version $(jam-version) ;
+ assert.false check-jam-version $(future-version) ;
+
+ assert.true version-less 0 : 1 ;
+ assert.false version-less 0 : 0 ;
+ assert.true version-less 1 : 2 ;
+ assert.false version-less 1 : 1 ;
+ assert.false version-less 2 : 1 ;
+ assert.true version-less 3 1 20 : 3 4 10 ;
+ assert.false version-less 3 1 10 : 3 1 10 ;
+ assert.false version-less 3 4 10 : 3 1 20 ;
+ assert.true version-less 3 1 20 5 1 : 3 4 10 ;
+ assert.false version-less 3 1 10 5 1 : 3 1 10 ;
+ assert.false version-less 3 4 10 5 1 : 3 1 20 ;
+ assert.true version-less 3 1 20 : 3 4 10 5 1 ;
+ assert.true version-less 3 1 10 : 3 1 10 5 1 ;
+ assert.false version-less 3 4 10 : 3 1 20 5 1 ;
+ assert.false version-less 3 1 10 : 3 1 10 0 0 ;
+ assert.false version-less 3 1 10 0 0 : 3 1 10 ;
+ assert.false version-less 3 1 10 0 : 3 1 10 0 0 ;
+ assert.false version-less 3 1 10 0 : 03 1 10 0 0 ;
+ assert.false version-less 03 1 10 0 : 3 1 10 0 0 ;
+
+ # TODO: Add tests for invalid input data being sent to version-less.
+}
Modified: branches/release/tools/build/v2/build/virtual-target.jam
==============================================================================
--- branches/release/tools/build/v2/build/virtual-target.jam (original)
+++ branches/release/tools/build/v2/build/virtual-target.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -4,10 +4,10 @@
# 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)
-# 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 transormation sequences, when it's not yet known
-# whether a particular target should be created at all.
+# 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
+# whether a particular target should be created at all.
import "class" : new ;
import errors ;
@@ -64,6 +64,7 @@
# The 'compile-action' and 'link-action' classes are not defined here but in
# builtin.jam modules. They are shown in the diagram to give the big picture.
+
# Models a potential target. It can be converted into a Jam target and used in
# building, if needed. However, it can be also dropped, which allows us to
# search for different transformations and select only one.
@@ -86,12 +87,15 @@
}
# Name of this target.
+ #
rule name ( ) { return $(self.name) ; }
# Project of this target.
+ #
rule project ( ) { return $(self.project) ; }
# Adds additional 'virtual-target' instances this one depends on.
+ #
rule depends ( d + )
{
self.dependencies = [ sequence.merge $(self.dependencies)
@@ -113,6 +117,7 @@
# file if 'scanner' is specified.
#
# If scanner is not specified then the actual target is returned.
+ #
rule actualize ( scanner ? )
{
local actual-name = [ actualize-no-scanner ] ;
@@ -146,12 +151,14 @@
# Sets up build actions for 'target'. Should call appropriate rules and set
# target variables.
+ #
rule actualize-action ( target )
{
errors.error "method should be defined in derived classes" ;
}
# Sets up variables on 'target' which specify its location.
+ #
rule actualize-location ( target )
{
errors.error "method should be defined in derived classes" ;
@@ -159,6 +166,7 @@
# If the target is a generated one, returns the path where it will be
# generated. Otherwise, returns an empty list.
+ #
rule path ( )
{
errors.error "method should be defined in derived classes" ;
@@ -166,6 +174,7 @@
# Returns the actual target name to be used in case when no scanner is
# involved.
+ #
rule actual-name ( )
{
errors.error "method should be defined in derived classes" ;
@@ -175,8 +184,8 @@
rule actualize-no-scanner ( )
{
# In fact, we just need to merge virtual-target with
- # abstract-virtual-target as the latter is the only class derived from
- # the former. But that's for later.
+ # abstract-file-target as the latter is the only class derived from the
+ # former. But that's for later.
errors.error "method should be defined in derived classes" ;
}
}
@@ -190,6 +199,7 @@
#
# The target's grist is concatenation of its project's location, properties of
# action (for derived files) and, optionally, value identifying the main target.
+#
class abstract-file-target : virtual-target
{
import project ;
@@ -230,12 +240,14 @@
# Sets the path. When generating target name, it will override any path
# computation from properties.
+ #
rule set-path ( path )
{
self.path = [ path.native $(path) ] ;
}
# Returns the currently set action.
+ #
rule action ( )
{
return $(self.action) ;
@@ -243,6 +255,7 @@
# Sets/gets the 'root' flag. Target is root if it directly corresponds to
# some variant of a main target.
+ #
rule root ( set ? )
{
if $(set)
@@ -256,12 +269,13 @@
# when target is brought into existance and is never changed after that. In
# particular, if a target is shared by a subvariant, only the first is
# stored.
- rule creating-subvariant ( s ? # If specified, specifies the value to set,
- # which should be a 'subvariant' class
- # instance.
+ #
+ rule creating-subvariant ( s ? # If specified, specifies the value to set,
+ # which should be a 'subvariant' class
+ # instance.
)
{
- if $(s) && ! $(self.creating-subvariant) && ! $(overwrite)
+ if $(s) && ! $(self.creating-subvariant)
{
self.creating-subvariant = $(s) ;
}
@@ -333,7 +347,6 @@
local grist = [ grist ] ;
local basename = [ path.native $(self.name) ] ;
self.actual-name = <$(grist)>$(basename) ;
-
}
return $(self.actual-name) ;
}
@@ -341,6 +354,7 @@
# Helper to 'actual-name', above. Computes a unique prefix used to
# distinguish this target from other targets with the same name creating
# different files.
+ #
rule grist ( )
{
# Depending on target, there may be different approaches to generating
@@ -379,11 +393,12 @@
# Given the target name specified in constructor, returns the name which
# should be really used, by looking at the <tag> properties. Tag properties
- # need to be specified as <tag>@rule-name. This makes Boost.Build call the
+ # need to be specified as <tag>@rule-name. This makes Boost Build call the
# specified rule with the target name, type and properties to get the new
# name. If no <tag> property is specified or the rule specified by <tag>
# returns nothing, returns the result of calling
# virtual-target.add-prefix-and-suffix.
+ #
rule _adjust-name ( specified-name )
{
local ps ;
@@ -468,6 +483,7 @@
# Appends the suffix appropriate to 'type/property-set' combination to the
# specified name and returns the result.
+#
rule add-prefix-and-suffix ( specified-name : type ? : property-set )
{
local suffix = [ type.generated-target-suffix $(type) : $(property-set) ] ;
@@ -546,7 +562,7 @@
DEPENDS $(target) : $(path) ;
common.MkDir $(path) ;
- # It's possible that the target name includes a directory too, for
+ # It is possible that the target name includes a directory too, for
# example when installing headers. Create that directory.
if $(target:D)
{
@@ -572,6 +588,10 @@
# 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
+ # possible ways to refer to the path (relative/absolute, extra ".",
+ # various "..", but should help in obvious cases.
+ DEPENDS $(target:G=e:R=$(path)) : $(target) ;
}
else
{
@@ -580,6 +600,7 @@
}
# Returns the directory for this target.
+ #
rule path ( )
{
if ! $(self.path)
@@ -612,6 +633,7 @@
}
# Returns nothing to indicate that the target's path is not known.
+ #
rule path ( )
{
return ;
@@ -631,7 +653,7 @@
# rule action-name ( targets + : sources * : properties * )
# Targets and sources are passed as actual Jam targets. The rule may not
# establish additional dependency relationships.
-
+#
class action
{
import "class" ;
@@ -687,6 +709,7 @@
}
# Generates actual build instructions.
+ #
rule actualize ( )
{
if ! $(self.actualized)
@@ -729,6 +752,7 @@
# Helper for 'actualize-sources'. For each passed source, actualizes it with
# the appropriate scanner. Returns the actualized virtual targets.
+ #
rule actualize-source-type ( sources * : property-set )
{
local result = ;
@@ -752,6 +776,7 @@
#
# New values will be *appended* to the variables. They may be non-empty if
# caller wants it.
+ #
rule actualize-sources ( sources * : property-set )
{
local dependencies = [ $(self.properties).get <dependency> ] ;
@@ -782,6 +807,7 @@
# the last chance to fix properties, for example to adjust includes to get
# generated headers correctly. Default implementation simply returns its
# argument.
+ #
rule adjust-properties ( property-set )
{
return $(property-set) ;
@@ -793,6 +819,7 @@
# properties out of nowhere. It's needed to distinguish virtual targets with
# different properties that are known to exist and have no actions which create
# them.
+#
class null-action : action
{
rule __init__ ( property-set ? )
@@ -816,6 +843,7 @@
# Class which acts exactly like 'action', except that its sources are not
# scanned for dependencies.
+#
class non-scanning-action : action
{
rule __init__ ( sources * : action-name + : property-set ? )
@@ -842,6 +870,7 @@
# name and source location for the project, and use that path to determine if
# the target was already created.
# 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.
@@ -876,6 +905,7 @@
# 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
# returned.
+#
rule register ( target )
{
local signature = [ sequence.join
@@ -901,8 +931,10 @@
{
local ps1 = [ $(a1).properties ] ;
local ps2 = [ $(a2).properties ] ;
- local p1 = [ $(ps1).base ] [ $(ps1).free ] [ $(ps1).dependency ] ;
- local p2 = [ $(ps2).base ] [ $(ps2).free ] [ $(ps2).dependency ] ;
+ 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) ;
@@ -925,9 +957,11 @@
}
-# Each target returned by 'register' is added to a recent-targets list, returned
-# by this function. This allows us to find all targets created when building a
-# given main target, even if the target... !!!MISSING TEXT HERE!!!
+# Each target returned by 'register' is added to a .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.
+#
rule recent-targets ( )
{
return $(.recent-targets) ;
@@ -941,6 +975,7 @@
# Returns all virtual targets ever created.
+#
rule all-targets ( )
{
return $(.all-targets) ;
@@ -949,6 +984,7 @@
# Returns all targets from 'targets' with types equal to 'type' or derived from
# it.
+#
rule select-by-type ( type : targets * )
{
local result ;
@@ -1007,6 +1043,7 @@
# 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.
+#
rule traverse ( target : include-roots ? : include-sources ? )
{
local result ;
@@ -1040,6 +1077,7 @@
# produced by the action. The rule-name and properties are set to
# 'new-rule-name' and 'new-properties', if those are specified. Returns the
# cloned action.
+#
rule clone-action ( action : new-project : new-action-name ? : new-properties ? )
{
if ! $(new-action-name)
@@ -1053,7 +1091,7 @@
local action-class = [ modules.peek $(action) : __class__ ] ;
local cloned-action = [ class.new $(action-class)
- [ $(action).sources ] : $(new-action-name) : $(new-properties) ] ;
+ [ $(action).sources ] : $(new-action-name) : $(new-properties) ] ;
local cloned-targets ;
for local target in [ $(action).targets ]
@@ -1145,6 +1183,7 @@
# indirectly, and either as sources, or as dependency properties. Targets
# referred to using the dependency property are returned as properties, not
# targets.
+ #
rule all-referenced-targets ( )
{
# Find directly referenced targets.
@@ -1173,10 +1212,11 @@
# referred by <implcit-dependecy> properties. For all targets of type
# 'target-type' (or for all targets, if 'target-type' is not specified), the
# result will contain <$(feature)>path-to-that-target.
+ #
rule implicit-includes ( feature : target-type ? )
{
local key = ii$(feature)-$(target-type:E="") ;
- if ! $($(key))-is-nonempty
+ if ! $($(key))-is-not-empty
{
local target-paths = [ all-target-directories $(target-type) ] ;
target-paths = [ sequence.unique $(target-paths) ] ;
Modified: branches/release/tools/build/v2/doc/src/advanced.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/advanced.xml (original)
+++ branches/release/tools/build/v2/doc/src/advanced.xml 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -7,15 +7,14 @@
<para>This section will provide the information necessary to create your own
projects using Boost.Build. The information provided here is relatively
- high-level, and <xref linkend="bbv2.reference"/> as
- well as the on-line help system must be used to obtain
- low-level documentation (see <xref linkend=
+ high-level, and <xref linkend="bbv2.reference"/> as well as the on-line help
+ system must be used to obtain low-level documentation (see <xref linkend=
"bbv2.reference.init.options.help"/>).</para>
- <para>Boost.Build actually consists of two parts - Boost.Jam, a
- build engine with its own interpreted language, and Boost.Build itself,
- implemented in Boost.Jam's language. The chain of events when
- you type <command>bjam</command> on the command line is:
+ <para>Boost.Build actually consists of two parts - Boost.Jam, a build engine
+ with its own interpreted language, and Boost.Build itself, implemented in
+ Boost.Jam's language. The chain of events when you type
+ <command>bjam</command> on the command line is:
<orderedlist>
<listitem>
<para>Boost.Jam tries to find Boost.Build and loads the top-level
@@ -23,9 +22,10 @@
linkend="bbv2.reference.init"/></para>
</listitem>
<listitem>
- <para>The top-level module loads user-defined configuration
- files, <filename>user-config.jam</filename> and <filename>site-config.jam</filename>, which define
- available toolsets.</para>
+ <para>The top-level module loads user-defined configuration files,
+ <filename>user-config.jam</filename> and
+ <filename>site-config.jam</filename>, which define available toolsets.
+ </para>
</listitem>
<listitem>
<para>The Jamfile in the current directory is read. That in turn
@@ -37,7 +37,7 @@
Boost.Build decides which targets should be built, and how. That
information is passed back to Boost.Jam, which takes care of
actually running commands.</para>
- </listitem>
+ </listitem>
</orderedlist>
</para>
@@ -57,45 +57,45 @@
How the build process works</link></para>
</listitem>
<listitem>
- <para>Some Basics about the Boost.Jam language. See
+ <para>Some Basics about the Boost.Jam language. See
<xref linkend="bbv2.advanced.jam_language"/>.
</para>
</listitem>
</itemizedlist>
</para>
-
+
<section id="bbv2.advanced.jam_language">
<title>Boost.Jam Language</title>
<para>This section will describe the basics of the Boost.Jam
language—just enough for writing Jamfiles. For more information,
- please see the <link linkend="bbv2.jam">Boost.Jam</link>
- documentation.</para>
+ please see the <link linkend="bbv2.jam">Boost.Jam</link> documentation.
+ </para>
- <para>Boost.Jam has an interpreted, procedural language.
- On the lowest level, a Boost.Jam program consists of variables and
+ <para><link linkend="bbv2.jam">Boost.Jam</link> has an interpreted,
+ procedural language. On the lowest level, a <link linkend="bbv2.jam">
+ Boost.Jam</link> program consists of variables and
<indexterm><primary>rule</primary></indexterm>
<firstterm>rules</firstterm> (the Jam term for function). They are grouped
- in modules—there's one global module and a number of named
- modules. Besides that, a Boost.Jam program contains classes and class
- instances.
- </para>
-
- <para>Syntantically, a Boost.Jam program consists of two kind of
- elements—keywords (which have a special meaning to Boost.Jam) and
- literals.
+ in modules—there's one global module and a number of named modules.
+ Besides that, a <link linkend="bbv2.jam">Boost.Jam</link> program contains
+ classes and class instances.</para>
+
+ <para>Syntantically, a <link linkend="bbv2.jam">Boost.Jam</link> program
+ consists of two kind of elements—keywords (which have a special
+ meaning to <link linkend="bbv2.jam">Boost.Jam</link>) and literals.
Consider this code:
<programlisting>
a = b ;</programlisting>
which assigns the value <literal>b</literal> to the variable
- <literal>a</literal>. Here, <literal>=</literal> and
- <literal>;</literal> are keywords, while <literal>a</literal> and
- <literal>b</literal> are literals.
+ <literal>a</literal>. Here, <literal>=</literal> and <literal>;</literal>
+ are keywords, while <literal>a</literal> and <literal>b</literal> are
+ literals.
<warning>
- <para>All syntax elements, even keywords, must be separated by
- spaces. For example, omitting the space character before
- <literal>;</literal> will lead to a syntax error.
+ <para>All syntax elements, even keywords, must be separated by spaces.
+ For example, omitting the space character before <literal>;</literal>
+ will lead to a syntax error.
</para>
</warning>
If you want to use a literal value that is the same as some keyword, the
@@ -103,11 +103,11 @@
<programlisting>
a = "=" ;</programlisting>
</para>
-
- <para>All variables in Boost.Jam have the same type—list of
- strings. To define a variable one assigns a value to it, like in the
- previous example. An undefined variable is the same as a variable with
- an empty value. Variables can be accessed with the
+
+ <para>All variables in <link linkend="bbv2.jam">Boost.Jam</link> have the
+ same type—list of strings. To define a variable one assigns a value
+ to it, like in the previous example. An undefined variable is the same as
+ a variable with an empty value. Variables can be accessed using the
<code>$(<replaceable>variable</replaceable>)</code> syntax. For example:
<programlisting>
a = $(b) $(c) ;</programlisting>
@@ -115,27 +115,28 @@
<para>
Rules are defined by specifying the rule name, the parameter names,
- and the allowed size of the list value for each parameter.
+ and the allowed size of the list value for each parameter.
<programlisting>
-rule <replaceable>example</replaceable>
+rule <replaceable>example</replaceable>
(
- <replaceable>parameter1</replaceable> :
- <replaceable>parameter2 ?</replaceable> :
+ <replaceable>parameter1</replaceable> :
+ <replaceable>parameter2 ?</replaceable> :
<replaceable>parameter3 +</replaceable> :
- <replaceable>parameter4 *</replaceable>
+ <replaceable>parameter4 *</replaceable>
)
{
// body
}</programlisting>
When this rule is called, the list passed as the first argument must
have exactly one value. The list passed as the second argument can
- either have one value of be empty. The two remaining arguments can
- be arbitrary long, but the third argument may not be empty.
+ either have one value of be empty. The two remaining arguments can be
+ arbitrarily long, but the third argument may not be empty.
</para>
- <para>The overview of Boost.Jam language statements is given below:
+ <para>The overview of <link linkend="bbv2.jam">Boost.Jam</link> language
+ statements is given below:
<programlisting>
-helper 1 : 2 : 3 ;
+helper 1 : 2 : 3 ;
x = [ helper 1 : 2 : 3 ] ;</programlisting>
This code calls the named rule with the specified arguments. When the
result of the call must be used inside some expression, you need to add
@@ -144,7 +145,7 @@
if cond { statements } [ else { statements } ]</programlisting>
This is a regular if-statement. The condition is composed of:
<itemizedlist>
- <listitem><para>Literals (true if at least one string is not empty)</para></listitem>
+ <listitem><para>Literals (true if at least one string is not empty)</para></listitem>
<listitem><para>Comparisons: <code>a
<replaceable>operator</replaceable> b</code> where
<replaceable>operator</replaceable> is one of <code>=</code>,
@@ -163,7 +164,7 @@
<varname>var</varname> to the element value.
<programlisting>
while cond { statements }</programlisting>
- Repeatedly execute statements while cond remains true upon entry.
+ Repeatedly execute statements while cond remains true upon entry.
<programlisting>
return values ;
</programlisting>This statement should be used only inside a
@@ -202,16 +203,17 @@
create-file-from-another $(<) $(>)
}
</programlisting>
- This specifies a named action called
- <literal>create-file-from-another</literal>. The text inside braces is the
- command to invoke. The <literal>$(<)</literal> variable will be expanded to list of
- generated files, and the <literal>$(>)</literal> variable will be expanded
- to the list of source files.
+ This specifies a named action called
+ <literal>create-file-from-another</literal>. The text inside braces is
+ the command to invoke. The <literal>$(<)</literal> variable will be
+ expanded to a list of generated files, and the
+ <literal>$(>)</literal> variable will be expanded to a list of
+ source files.
</para>
- <para>To flexibly adjust command line, you can define a rule with the
- same name as the action, and taking three parameters -- targets, sources
- and properties. For example:
+ <para>To flexibly adjust command line, you can define a rule with the same
+ name as the action, and taking three parameters -- targets, sources and
+ properties. For example:
<programlisting>
rule create-file-from-another ( targets * : sources * : properties * )
{
@@ -226,14 +228,15 @@
}
</programlisting>
In this example, the rule checks if certain build property is specified.
- If so, it sets variable <varname>OPIONS</varname> that's used inside
- action. Note that the variable is set "on targets" -- the value will
- be only visible inside action, not globally. Were it set globally,
- using variable named <varname>OPTIONS</varname> in two unrelated
- actions would be impossible.
+ If so, it sets variable <varname>OPIONS</varname> that is then used inside
+ the action. Note that the variables set "on a target" will be visible only
+ inside actions building that target, not globally. Were they set globally,
+ using variable named <varname>OPTIONS</varname> in two unrelated actions
+ would be impossible.
</para>
- <para>More details can be found in Jam reference, <xref linkend="jam.language.rules"/>
+ <para>More details can be found in Jam reference,
+ <xref linkend="jam.language.rules"/>
</para>
</section>
@@ -243,35 +246,33 @@
<para>The Boost.Build configuration is specified in the file
<filename>user-config.jam</filename>. You can edit the one in the top-level
- directory of Boost.Build installation or create a copy in your home directory
- and edit that. (See <xref linkend="bbv2.reference.init.config"/> for the
- exact search paths.) The primary function of that file is to declare which
- compilers and other tools are available. The simplest syntax to configure
- a tool is:
+ directory of Boost.Build installation or create a copy in your home
+ directory and edit that. (See <xref linkend="bbv2.reference.init.config"/>
+ for the exact search paths.) The primary function of that file is to declare
+ which compilers and other tools are available. The simplest syntax to
+ configure a tool is:
<programlisting>
-using <replaceable>tool-name</replaceable> ;
-</programlisting>
- The <functionname>using</functionname> rule is given a name of tool, and will make that tool
- available to Boost.Build. For example, <code>using gcc ;</code> will make the gcc compiler
- available.
+using <replaceable>tool-name</replaceable> ;
+</programlisting>
+ The <functionname>using</functionname> rule is given a name of tool, and
+ will make that tool available to Boost.Build. For example,
+ <code>using gcc ;</code> will make the gcc compiler available.
</para>
<para>
- Since nothing but a tool name is specified, Boost.Build will
- pick some default settings. For example, it will use the
- <command>gcc</command> executable found in the
- <envar>PATH</envar>, or look in some known installation
- locations. In most cases, this strategy works automatically. In
- case you have several versions of a compiler, it's installed in
- some unusual location, or you need to tweak its configuration,
- you'll need to pass additional parameters to the
- <functionname>using</functionname> rule. The parameters to
- <functionname>using</functionname> can be different for each
- tool. You can obtain specific documentation for any tool's
+ Since nothing but a tool name is specified, Boost.Build will pick some
+ default settings. For example, it will use the <command>gcc</command>
+ executable found in the <envar>PATH</envar>, or look in some known
+ installation locations. In most cases, this strategy works automatically.
+ In case you have several versions of a compiler, it's installed in some
+ unusual location, or you need to tweak its configuration, you'll need to
+ pass additional parameters to the <functionname>using</functionname> rule.
+ The parameters to <functionname>using</functionname> can be different for
+ each tool. You can obtain specific documentation for any tool's
configuration parameters by invoking
<programlisting>
-bjam --help <replaceable>tool-name</replaceable>.init
+bjam --help <replaceable>tool-name</replaceable>.init
</programlisting>
</para>
<para>
@@ -285,28 +286,23 @@
<!-- the previous text here was really confusing -->
</para>
- <para>The <parameter class="function">version</parameter>
- parameter identifies the toolset version, in case you have
- several installed. It can have any form you like, but
- it's recommended that you use a numeric identifier like
- <literal>7.1</literal>.
+ <para>The <parameter class="function">version</parameter> parameter
+ identifies the toolset version, in case you have several installed. It can
+ have any form you like, but it is recommended that you use a numeric
+ identifier like <literal>7.1</literal>.
</para>
<para>
- The <parameter class="function">invocation-command</parameter>
- parameter is the command that must be executed to run the
- compiler. This parameter can usually be omitted if the compiler
- executable
+ The <parameter class="function">invocation-command</parameter> parameter
+ is the command that must be executed to run the compiler. This parameter
+ can usually be omitted if the compiler executable
<itemizedlist>
- <listitem><para>has its “usual
- name” and is in the <envar>PATH</envar>,
- or</para></listitem>
- <listitem><para>was installed in a standard
- “installation directory”,
- or</para></listitem>
-
- <listitem><para>can be found through a global mechanism like the
- Windows registry.</para></listitem>
+ <listitem><para>has its “usual name” and is in the
+ <envar>PATH</envar>, or</para></listitem>
+ <listitem><para>was installed in a standard “installation
+ directory”, or</para></listitem>
+ <listitem><para>can be found using a global system like the Windows
+ registry.</para></listitem>
</itemizedlist>
For example:
@@ -382,7 +378,7 @@
using gcc : 3.4 : : <compileflags>-m64 <linkflags>-m64 ;
</programlisting>
</para>
-
+
</section>
<section id="bbv2.advanced.invocation">
@@ -397,7 +393,7 @@
<para>To build specific targets, specify them on the command line:
<screen>
-bjam lib1 subproject//lib2
+bjam lib1 subproject//lib2
</screen>
</para>
@@ -417,12 +413,12 @@
<para>Boost.Build recognizes the following command line options.</para>
<variablelist>
-
+
<varlistentry>
<term><option>--clean</option></term>
<listitem>
- <para>Cleans all targets in the current directory and
- in any subprojects. Note that unlike the <literal>clean</literal>
+ <para>Cleans all targets in the current directory and
+ in any subprojects. Note that unlike the <literal>clean</literal>
target in make, you can use <literal>--clean</literal>
together with target names to clean specific targets.</para>
</listitem>
@@ -431,8 +427,8 @@
<varlistentry>
<term><option>--clean-all</option></term>
<listitem>
- <para>Cleans all targets,
- no matter where they are defined. In particular, it will clean targets
+ <para>Cleans all targets,
+ no matter where they are defined. In particular, it will clean targets
in parent Jamfiles, and targets defined under other project roots.
</para>
</listitem>
@@ -444,8 +440,8 @@
<para>Changes build directories for all project roots being built. When
this option is specified, all Jamroot files should declare project name.
The build directory for the project root will be computed by concatanating
- the value of the <option>--build-dir</option> option, the project name
- specified in Jamroot, and the build dir specified in Jamroot
+ the value of the <option>--build-dir</option> option, the project name
+ specified in Jamroot, and the build dir specified in Jamroot
(or <literal>bin</literal>, if none is specified).
</para>
@@ -477,7 +473,7 @@
<varlistentry>
<term><option>--debug-configuration</option></term>
<listitem>
- <para>Produces debug information about loading of Boost.Build
+ <para>Produces debug information about loading of Boost.Build
and toolset files.</para>
</listitem>
</varlistentry>
@@ -493,7 +489,7 @@
<varlistentry>
<term><option>--debug-generators</option></term>
<listitem>
- <para>Produces debug output from generator search process.
+ <para>Produces debug output from generator search process.
Useful for debugging custom generators.
</para>
</listitem>
@@ -515,11 +511,11 @@
</para>
</listitem>
</varlistentry>
-
+
</variablelist>
- <para>For complete specification of command line syntax, see
+ <para>For complete specification of command line syntax, see
<xref linkend="bbv2.reference.init.args"/>
</para>
@@ -546,7 +542,7 @@
<!-- I think we maybe ought to be talking about a common
_signature_ here, having already explained Boost.Jam function
- signatures at the beginning of this chapter. Then we could show
+ signatures at the beginning of this chapter. Then we could show
( main-target-name : sources * : requirements * : default-build * : usage-requirements * )
instead. More precise.
@@ -575,21 +571,21 @@
(‘<code>_</code>’).
</simpara>
</listitem>
-
+
<listitem>
<simpara>
<parameter>sources</parameter> is the list of source files and other main
- targets that must be combined.
+ targets that must be combined.
</simpara>
</listitem>
-
+
<listitem>
<simpara>
<parameter>requirements</parameter> is the list of properties that must always
be present when this main target is built.
</simpara>
</listitem>
-
+
<listitem>
<simpara>
<parameter>default-build</parameter> is the list of properties that will be used
@@ -597,7 +593,7 @@
specified, e.g. on the command line or by propagation from a dependent target.
</simpara>
</listitem>
-
+
<listitem>
<simpara>
<parameter>usage-requirements</parameter> is the list of properties that will be
@@ -607,7 +603,7 @@
</listitem>
</itemizedlist>
- <para>
+ <para>
Some main target rules have a different list of parameters as explicitly
stated in their documentation.
</para>
@@ -615,7 +611,7 @@
<para>The actual requirements for a target are obtained by refining
requirements of the project where a target is declared with the
explicitly specified requirements. The same is true for
- usage-requirements. More details can be found in
+ usage-requirements. More details can be found in
<xref linkend="bbv2.reference.variants.proprefine"/>
</para>
@@ -631,7 +627,7 @@
prefixes.
</para>
- <para>The name of a main target can contain alphanumeric characters,
+ <para>The name of a main target can contain alphanumeric characters,
dashes, undescores and dots. The entire
name is significant when resolving references from other targets. For determining filenames, only the
part before the first dot is taken. For example:</para>
@@ -641,7 +637,7 @@
</programlisting>
<para>will generate two files named <filename>test.obj</filename> (in two different directories), not
two files named <filename>test.release.obj</filename> and <filename>test.debug.obj</filename>.
- </para>
+ </para>
</section>
@@ -656,7 +652,7 @@
<functionname>glob</functionname> rule. Here are two examples:</para>
<programlisting>
exe a : a.cpp ; # a.cpp is the only source file
-exe b : [ glob *.cpp ] ; # all .cpp files in this directory are sources
+exe b : [ glob *.cpp ] ; # all .cpp files in this directory are sources
</programlisting>
<para>
Unless you specify a file with an absolute path, the name is
@@ -677,7 +673,7 @@
the double slash is first looked up as project name, and then as directory
name. For example:
</para>
-
+
<programlisting>
lib helper : helper.cpp ;
exe a : a.cpp helper ;
@@ -712,18 +708,18 @@
<programlisting>
lib util : util.cpp : <link>static ;
obj main : main.cpp : <optimization>off ;
-</programlisting>
+</programlisting>
</para>
<para id="bbv2.advanced.targets.requirements.conditional">Sometimes, particular relationships need to be maintained
- among a target's build properties. This can be achieved with
+ among a target's build properties. This can be achieved with
<firstterm>conditional
requirements</firstterm>. For example, you might want to set
specific <code>#defines</code> when a library is built as shared,
or when a target's <code>release</code> variant is built in
release mode.
<programlisting>
-lib network : network.cpp
+lib network : network.cpp
: <emphasis role="bold"><link>shared:<define>NEWORK_LIB_SHARED</emphasis>
<variant>release:<define>EXTRA_FAST
;
@@ -732,7 +728,7 @@
In the example above, whenever <filename>network</filename> is
built with <code><link>shared</code>,
<code><define>NEWORK_LIB_SHARED</code> will be in its
- properties, too.
+ properties, too.
</para>
<para>You can use several properties in the condition, for example:
@@ -744,12 +740,12 @@
</para>
<para id="bbv2.advanced.targets.requirements.indirect">
- A more powerful variant of conditional requirements
+ A more powerful variant of conditional requirements
is <firstterm>indirect conditional requirements</firstterm>.
You can provide a rule that will be called with the current build properties and can compute additional properties
to be added. For example:
<programlisting>
-lib network : network.cpp
+lib network : network.cpp
: <conditional>@my-rule
;
rule my-rule ( properties * )
@@ -760,7 +756,7 @@
result += <define>USE_INLINE_ASSEMBLER ;
}
return $(result) ;
-}
+}
</programlisting>
This example is equivalent to the previous one, but for complex cases, indirect conditional
requirements can be easier to write and understand.
@@ -785,15 +781,15 @@
Here, <code>test1</code> inherits project requirements and will always
be built in multi-threaded mode. The <code>test2</code> target
<emphasis>overrides</emphasis> project's requirements and will
- always be built in single-threaded mode. In contrast, the
+ always be built in single-threaded mode. In contrast, the
<code>test3</code> target <emphasis>removes</emphasis> a property
from project requirements and will be built either in single-threaded or
multi-threaded mode depending on which variant is requested by the
user.</para>
- <para>Note that the removal of requirements is completely textual:
+ <para>Note that the removal of requirements is completely textual:
you need to specify exactly the same property to remove it.</para>
-
+
</section>
<section>
@@ -838,7 +834,7 @@
parameter may include calls to other main rules. For example:</para>
<programlisting>
-exe hello : hello.cpp
+exe hello : hello.cpp
[ obj helpers : helpers.cpp : <optimization>off ] ;</programlisting>
<para>
@@ -868,7 +864,7 @@
because they allow us to group related targets together, define
properties common to all those targets, and assign a symbolic
name to the project that can be used in referring to its
- targets.
+ targets.
</para>
<para>Projects are named using the
@@ -883,11 +879,11 @@
of attribute names along with its handling is also shown in
the table below. For example, it is possible to write:
<programlisting>
-project tennis
- : requirements <threading>multi
+project tennis
+ : requirements <threading>multi
: default-build release
;
-</programlisting>
+</programlisting>
</para>
<para>The possible attributes are listed below.</para>
@@ -897,7 +893,7 @@
unrelated to filesystem, such as "boost/thread". <link linkend=
"bbv2.reference.ids">Target references</link> make use of project ids to
specify a target.</para>
- <!--
+ <!--
This is actually spelled "project-id," isn't it? You
have to fix all of these and use a code font. Also below
in the table.
@@ -911,7 +907,7 @@
<para><emphasis>Default build</emphasis> is the build request that should be
used when no build request is specified explicitly.</para>
- <!--
+ <!--
This contradicts your earlier description of default
build and I believe it is incorrect. Specifying a build
request does not neccessarily render default build
@@ -930,73 +926,73 @@
<thead>
<row>
<entry>Attribute</entry>
-
+
<entry>Name</entry>
-
+
<entry>Default value</entry>
-
+
<entry>Handling by the <functionname>project</functionname>
rule</entry>
</row>
</thead>
-
+
<tbody>
-
+
<row>
<entry>Project id</entry>
-
+
<entry>none</entry>
-
+
<entry>none</entry>
-
+
<entry>Assigned from the first parameter of the 'project' rule.
It is assumed to denote absolute project id.</entry>
</row>
-
+
<row>
<entry>Source location</entry>
-
+
<entry><literal>source-location</literal></entry>
-
+
<entry>The location of jamfile for the project</entry>
-
+
<entry>Sets to the passed value</entry>
</row>
-
+
<row>
<entry>Requirements</entry>
-
+
<entry><literal>requirements</literal></entry>
-
+
<entry>The parent's requirements</entry>
-
+
<entry>The parent's requirements are refined with the passed
requirement and the result is used as the project
requirements.</entry>
</row>
-
+
<row>
<entry>Default build</entry>
-
+
<entry><literal>default-build</literal></entry>
-
+
<entry>none</entry>
-
+
<entry>Sets to the passed value</entry>
</row>
-
+
<row>
<entry>Build directory</entry>
-
+
<entry><literal>build-dir</literal></entry>
-
+
<entry>Empty if the parent has no build directory set.
Otherwise, the parent's build directory with the
relative path from parent to the current project
appended to it.
</entry>
-
+
<entry>Sets to the passed value, interpreted as relative to the
project's location.</entry>
</row>
@@ -1007,7 +1003,7 @@
<para>Besides defining projects and main targets, Jamfiles
often invoke various utility rules. For the full list of rules
- that can be directly used in Jamfile see
+ that can be directly used in Jamfile see
<xref linkend="bbv2.reference.rules"/>.
</para>
@@ -1028,7 +1024,7 @@
subprojects, so that every definition made in a parent project
is always available to its children. The loading order of any
other projects is unspecified. Even if one project refers to
- another via the <code>use-project</code> or a target reference,
+ another via the <code>use-project</code> or a target reference,
no specific order should be assumed.
</para>
@@ -1038,7 +1034,7 @@
Boost.Build won't misinterpret a directory above it as the
project root just because the directory contains a Jamfile.
<!-- The logic of the previous reasoning didn't hang together -->
- </para>
+ </para>
</note>
<!-- All this redundancy with the tutorial is bad. The tutorial
@@ -1047,12 +1043,12 @@
perfectly appropriate to start a user guide with that kind
of material. -->
</section>
-
+
<section id="bbv2.advanced.build_process">
<title>The Build Process</title>
<para>When you've described your targets, you want Boost.Build to run the
- right tools and create the needed targets.
+ right tools and create the needed targets.
<!-- That sentence is awkward and doesn't add much. -->
This section will describe
two things: how you specify what to build, and how the main targets are
@@ -1061,7 +1057,7 @@
<para>The most important thing to note is that in Boost.Build, unlike
other build tools, the targets you declare do not correspond to specific
- files. What you declare in a Jamfile is more like a âmetatarget.â
+ files. What you declare in a Jamfile is more like a âmetatarget.â
<!-- Do we need a new word? We already have âmain target.â If
you're going to introduce âmetatargetâ you should at least
tie it together with the main target concept. It's too
@@ -1077,7 +1073,7 @@
<para>
This means that for Boost.Build, you cannot directly obtain a build
variant from a Jamfile. There could be several variants requested by the
- user, and each target can be built with different properties.
+ user, and each target can be built with different properties.
</para>
</tip>
@@ -1091,7 +1087,7 @@
bjam app1 lib1//lib1 toolset=gcc variant=debug optimization=full
</programlisting>
would build two targets, "app1" and "lib1//lib1" with the specified
- properties. You can refer to any targets, using
+ properties. You can refer to any targets, using
<link linkend="bbv2.reference.ids">target id</link> and specify arbitrary
properties. Some of the properties are very common, and for them the name
of the property can be omitted. For example, the above can be written as:
@@ -1110,7 +1106,7 @@
explanation is provided, and more details are given in <xref
linkend="bbv2.reference.buildprocess"/>.
<orderedlist>
-
+
<listitem><para>Applying default build. If the default-build
property of a target specifies a value of a feature that is not
present in the build request, that value is added.</para>
@@ -1120,21 +1116,21 @@
the reader will be confused.
-->
</listitem>
-
+
<listitem><para>Selecting the main target alternative to use. For
each alternative we look how many properties are present both in
alternative's requirements, and in build request. The
alternative with large number of matching properties is selected.
</para></listitem>
-
- <listitem><para>Determining "common" properties.
+
+ <listitem><para>Determining "common" properties.
<!-- It would be nice to have a better name for this. But
even more importantly, unless you say something about
the reason for choosing whatever term you use, the
reader is going to wonder what it means. -->
The build request
is <link linkend="bbv2.reference.variants.proprefine">refined</link>
- with target's requirements.
+ with target's requirements.
<!-- It's good that you have the links here and below,
but I'm concerned that it doesn't communicate well
in print and there's not enough information for the
@@ -1144,7 +1140,7 @@
requirements are handled as well. Finally, default values of
features are added.
</para></listitem>
-
+
<listitem><para>Building targets referred by the sources list and
dependency properties. The list of sources and the properties
can refer to other target using <link
@@ -1153,38 +1149,34 @@
linkend="bbv2.reference.features.attributes.propagated">propagated</link>
properties, refine them by explicit properties specified in the
target reference, and pass the resulting properties as build
- request to the other target.
+ request to the other target.
</para></listitem>
-
+
<listitem><para>Adding the usage requirements produced when building
dependencies to the "common" properties. When dependencies are
- built in the previous step, they return
+ built in the previous step, they return
<!-- don't assume reader has a mental model for BB internals! -->
both the set of created
"real" targets, and usage requirements. The usage requirements
are added to the common properties and the resulting property
- set will be used for building the current target.
+ set will be used for building the current target.
</para></listitem>
-
+
<listitem><para>Building the target using generators. To convert the
sources to the desired type, Boost.Build uses "generators" ---
- objects that correspond to tools like compilers and
- linkers. Each generator declares what type of targets it
- <!-- Was "in." Why are these short and unmistakable
- words so commonly misspelled? -->
- can
- produce and what type of sources it requires. Using this
- information, Boost.Build determines which generators must be run
- to produce a specific target from specific sources. When
- generators are run, they return the "real" targets.
+ objects that correspond to tools like compilers and linkers. Each
+ generator declares what type of targets it can produce and what
+ type of sources it requires. Using this information, Boost.Build
+ determines which generators must be run to produce a specific
+ target from specific sources. When generators are run, they return
+ the "real" targets.
</para></listitem>
-
+
<listitem><para>Computing the usage requirements to be returned. The
- conditional properties in usage requirements are expanded
+ conditional properties in usage requirements are expanded
<!-- what does "expanded" mean? -->
- and the
- result is returned.</para></listitem>
- </orderedlist>
+ and the result is returned.</para></listitem>
+ </orderedlist>
</para>
</section>
@@ -1213,22 +1205,20 @@
</para>
<para>The Jamfile for a project can include a number of
- <code>build-project</code> rule calls
- <!-- A comma would only be correct here in German -->
- that specify additional projects
- to be built.
+ <code>build-project</code> rule calls that specify additional projects to
+ be built.
</para>
</section>
</section>
-
+
</chapter>
<!--
Local Variables:
mode: nxml
- sgml-indent-data: t
+ sgml-indent-data: t
sgml-parent-document: ("userman.xml" "chapter")
sgml-set-face: t
End:
Modified: branches/release/tools/build/v2/doc/src/extending.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/extending.xml (original)
+++ branches/release/tools/build/v2/doc/src/extending.xml 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -130,14 +130,14 @@
automatically generate necessary build actions only because you
specify the desired type (using the different main target rules), and
because Boost.Build can guess the type of sources from their
- extensions.
+ extensions.
</para>
<para>The first two parameters for the <code>type.register</code> rule
are the name of new type and the list of extensions associated with
it. A file with an extension from the list will have the given target
type. In the case where a target of the declared type is generated
- from other sources, the first specified extension will be used.
+ from other sources, the first specified extension will be used.
</para>
<para>Sometimes you want to change the suffix used for generated targets
@@ -149,7 +149,7 @@
</programlisting>
</para>
- <para>A new target type can be inherited from an existing one.
+ <para>A new target type can be inherited from an existing one.
<programlisting>
type.register PLUGIN : : SHARED_LIB ;
</programlisting>
@@ -174,10 +174,10 @@
<section id="bbv2.extending.scanners">
<title>Scanners</title>
<para>
- Sometimes, a file can refer to other files via some include
- mechanism. To make Boost.Build track dependencies to the included
- files, you need to provide a scanner. The primary limitation is that
- only one scanner can be assigned to a target type.
+ Sometimes, a file can refer to other files via some include system. To
+ make Boost.Build track dependencies between included files, you need
+ to provide a scanner. The primary limitation is that only one scanner
+ can be assigned to a target type.
</para>
<para>First, we need to declare a new class for the scanner:
@@ -189,7 +189,7 @@
return "//###include[ ]*\"([^\"]*)\"" ;
}
}
-</programlisting>
+</programlisting>
All the complex logic is in the <code>common-scanner</code>
class, and you only need to override the method that returns
the regular expression to be used for scanning. The
@@ -221,7 +221,7 @@
</section>
</section>
-
+
<section id="bbv2.extending.tools">
<title>Tools and generators</title>
<para>
@@ -319,7 +319,7 @@
<!-- What is the point of this __init__ function?? -->
}
-generators.register
+generators.register
[ new custom-generator verbatim.inline-file : VERBATIM : CPP ] ;
</programlisting>
This generator will work exactly like the
@@ -335,15 +335,13 @@
converted to the right types to actually create the result.
</para>
- <para>The <code>generated-target</code> <!-- Is it generated-target or generated-targets? -->
- method can be overridden
- when you want to add additional properties to the generated
- targets or use additional sources. For a real-life example,
- suppose you have a program analysis tool that should be given a
- name of executable and the list of all sources. Naturally, you
- don't want to list all source files manually. Here's how the
- <code>generated-targets</code> method can find the list of
- sources automatically:
+ <para>The <code>generated-targets</code> method can be overridden when you
+ want to add additional properties to the generated targets or use
+ additional sources. For a real-life example, suppose you have a program
+ analysis tool that should be given a name of executable and the list of
+ all sources. Naturally, you don't want to list all source files
+ manually. Here's how the <code>generated-targets</code> method can find
+ the list of sources automatically:
<programlisting>
class itrace-generator : generator {
....
@@ -365,13 +363,13 @@
generators.register [ new itrace-generator nm.itrace : EXE : ITRACE ] ;
</programlisting>
The <code>generated-targets</code> method will be called with a single
- source target of type <literal>EXE</literal>. The call to
+ source target of type <literal>EXE</literal>. The call to
<code>virtual-target.traverse</code> will return all targets the
executable depends on, and we further find files that are not
produced from anything. <!-- What does "not produced from anything" mean? -->
The found targets are added to the sources.
</para>
-
+
<para>The <code>run</code> method can be overriden to completely
customize the way the generator works. In particular, the conversion of
sources to the desired types can be completely customized. Here's
@@ -384,7 +382,7 @@
done:
<programlisting>
rule run ( project name ? : property-set : sources * )
-{
+{
local python ;
for local s in $(sources)
{
@@ -402,26 +400,26 @@
libs += $(s) ;
}
}
-
+
local new-sources ;
for local s in $(sources)
{
- if [ type.is-derived [ $(s).type ] CPP ]
+ if [ type.is-derived [ $(s).type ] CPP ]
{
local name = [ $(s).name ] ; # get the target's basename
- if $(name) = [ $(python).name ]
+ if $(name) = [ $(python).name ]
{
name = $(name)_ext ; # rename the target
- }
+ }
new-sources += [ generators.construct $(project) $(name) :
PYTHON_EXTENSION : $(property-set) : $(s) $(libs) ] ;
}
}
-
- result = [ construct-result $(python) $(new-sources) : $(project) $(name)
- : $(property-set) ] ;
-}
-</programlisting>
+
+ result = [ construct-result $(python) $(new-sources) : $(project) $(name)
+ : $(property-set) ] ;
+}
+</programlisting>
<!-- Why are we doing this with a generator??? It seems
insane. We could just use a nice front-end rule that
calls some normal target-creation rules. No? -->
@@ -430,16 +428,16 @@
sources. For each C++ source we create a separate Python extension by
calling <code>generators.construct</code> and passing the C++ source
and the libraries. At this point, we also change the extension's name,
- if necessary.
+ if necessary.
</para>
-
+
</section>
<section id="bbv2.extending.features">
<title>Features</title>
<para>
- Often, we need to control the options passed the invoked tools. This
+ Often, we need to control the options passed the invoked tools. This
is done with features. Consider an example:
<programlisting>
# Declare a new free feature
@@ -494,9 +492,9 @@
linkend="bbv2.faq.external"/> for an example of very smart usage of that
feature). Of course one should always strive to use portable
features, but these are still be provided as a backdoor just to make
- sure Boost.Build does not take away any control from the user.
+ sure Boost.Build does not take away any control from the user.
</para>
-
+
<para>
Using portable features is a good idea because:
<itemizedlist>
@@ -510,7 +508,7 @@
<!-- It's a computer program. It doesn't "care" about options -->
</para>
</listitem>
-
+
<listitem>
<para>Unlike with ârawâ features, you don't need to use
specific command-line flags in your Jamfile, and it will be
@@ -519,7 +517,7 @@
</listitem>
</itemizedlist>
</para>
-
+
<bridgehead>Steps for adding a feauture</bridgehead>
<!-- This section is redundant with the previous one -->
<para>Adding a feature requires three steps:
@@ -531,27 +529,28 @@
attributes</link>:
<itemizedlist>
- <listitem><para>if a feature has several values<!-- what do you mean by that?? --> and
- significantly affects the build, make it âpropagated,â so that the
- whole project is built with the same value by
- default</para></listitem>
-
- <listitem><para>if a feature does not have a fixed
- list of values, it must be âfree.â For example, the
- <code>include</code> feature is a free
- feature.</para></listitem>
-
- <listitem><para>if a feature is used to refer to a
- path relative to the Jamfile, it must be a âpathâ
- feature. <code>include</code> is also a path
- feature.</para></listitem>
-
+ <listitem><para>if you want a feature value set for one target
+ to automaticaly propagate to its dependant targets then make it
+ âpropagatedâ. <!-- Examples needed. --></para></listitem>
+
+ <listitem><para>if a feature does not have a fixed list of
+ values, it must be âfree.â For example, the <code>include
+ </code> feature is a free feature.</para></listitem>
+
+ <listitem><para>if a feature is used to refer to a path relative
+ to the Jamfile, it must be a âpathâ feature. Such features will
+ also get their values automatically converted to Boost Build's
+ internal path representation. For example, <code>include</code>
+ is a path feature.</para></listitem>
+
<listitem><para>if feature is used to refer to some target, it
- must be a âdependencyâ feature. <!-- for example? --></para></listitem>
+ must be a âdependencyâ feature. <!-- for example? --></para>
+
+ <!-- Any other feature attributes? -->
+ </listitem>
</itemizedlist>
</para>
</listitem>
-
<listitem><para>Representing the feature value in a
target-specific variable. Build actions are command
@@ -570,13 +569,13 @@
<para>Here's another example.
Let's see how we can make a feature that refers to a target. For example,
- when linking dynamic libraries on windows, one sometimes needs to specify
- "DEF file", telling what functions should be exported. It would be nice to
- use this file like this:
+ when linking dynamic libraries on Windows, one sometimes needs to
+ specify a "DEF file", telling what functions should be exported. It
+ would be nice to use this file like this:
<programlisting>
lib a : a.cpp : <def-file>a.def ;
</programlisting>
-<!-- Why would that be nice? It seems to me that having a.def in the sources is the obvious and much nicer thing to do:
+<!-- Why would that be nice? It seems to me that having a.def in the sources is the obvious and much nicer thing to do:
lib a : a.cpp a.def ;
-->
@@ -605,9 +604,9 @@
</programlisting>
<!-- And that line does... what? -->
</para></listitem>
-
+
<listitem><para>Since the DEF_FILE variable is not used by the
-msvc.link action,
+msvc.link action,
<!-- It's not? You just told us that MSVC "cares" about DEF files. I
presume that means that it uses them in some appropriate way? -->
we need to modify it to be:
@@ -619,8 +618,8 @@
}
</programlisting>
</para>
-
-
+
+
<para> Note the <code>bind DEF_FILE</code> part. It tells
bjam to translate the internal target name in
<varname>DEF_FILE</varname> to a corresponding filename in
@@ -642,11 +641,11 @@
DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
}
</programlisting>
-<!-- You *must* explain the part in [...] above. It's completely opaque to the casual reader -->
+<!-- You *must* explain the part in [...] above. It's completely opaque to the casual reader -->
This is needed to accomodate some bug in bjam, which hopefully
will be fixed one day.
- <!-- This is *NOT* a bug!! Anyway, BBv2 shouild handle this automatically. Why doesn't it? -->
+ <!-- This is *NOT* a bug!! Anyway, BBv2 shouild handle this automatically. Why doesn't it? -->
</para></listitem>
</orderedlist>
@@ -654,7 +653,7 @@
<bridgehead>Variants and composite features.</bridgehead>
<para>Sometimes you want to create a shortcut for some set of
- features. For example, <code>release</code> is a value of
+ features. For example, <code>release</code> is a value of
<code><variant></code> and is a shortcut for a set of features.
</para>
@@ -673,7 +672,7 @@
</para>
<para>You are not restricted to using the <code>variant</code> feature
- only.
+ only.
<!-- What do you mean by that? How is defining a new feature related to what came before? -->
Here's example that defines a brand new feature:
<programlisting>
@@ -685,11 +684,11 @@
above is at best confusing and unexplained -->
This will allow you to specify the value of feature
<code>parallelism</code>, which will expand to link to the necessary
- library.
+ library.
</para>
-
+
</section>
-
+
<section id="bbv2.extending.rules">
<title>Main target rules</title>
<para>
@@ -705,7 +704,7 @@
rule is already defined for you! When you define a new type, Boost.Build
automatically defines a corresponding rule. The name of the rule is
obtained from the name of the type, by downcasing all letters and
- replacing underscores with dashes.
+ replacing underscores with dashes.
<!-- This strikes me as needless complexity, and confusing. Why
do we have the uppercase-underscore convention for target
types? If we just dropped that, the rule names could be
@@ -723,7 +722,7 @@
and import that module, you'll be able to use the rule "obfuscated-cpp"
in Jamfiles, which will convert source to the OBFUSCATED_CPP type.
</para>
-
+
<para>
The second way is to write a wrapper rule that calls any of the existing
rules. For example, suppose you have only one library per directory and
@@ -816,7 +815,7 @@
<listitem><para>Check for multiple initialization. A user can try to
initialize the module several times. You need to check for this
and decide what to do. Typically, unless you support several
- versions of a tool, duplicate initialization is a user error.
+ versions of a tool, duplicate initialization is a user error.
<!-- Why should that be typical? -->
If the
tool's version can be specified during initialization, make sure the
@@ -854,7 +853,7 @@
</para>
-
+
</section>
@@ -862,7 +861,7 @@
<!--
Local Variables:
- sgml-indent-data: t
+ sgml-indent-data: t
sgml-parent-document: ("userman.xml" "chapter")
sgml-set-face: t
End:
Modified: branches/release/tools/build/v2/doc/src/fragments.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/fragments.xml (original)
+++ branches/release/tools/build/v2/doc/src/fragments.xml 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -6,53 +6,54 @@
<section id="root_option">
<varlistentry>
<term><literal>root</literal></term>
-
- <!-- At present, this option is only used to set LD_LIBRARY_PATH
- when running tests, and matters only if compiler's lib directory
- is not in LD_LIBRARY_PATH -->
-
- <listitem><para>Specifies root directory of the compiler
- installation. This option is necessary only if it's not possible
- to detect this information from the compiler command—for
- example if the specified compiler command is a user script. </para>
- </listitem>
+
+ <!-- At present, this option is only used to set LD_LIBRARY_PATH when
+ running tests, and matters only if compiler's lib directory is not in
+ LD_LIBRARY_PATH. -->
+
+ <listitem><para>Specifies root directory of the compiler installation.
+ This option is necessary only if it is not possible to detect this
+ information from the compiler command—for example if the specified
+ compiler command is a user script.</para></listitem>
</varlistentry>
</section>
<section id="common_options">
-
+
+ <!-- This most likely needs splitting into common_options,
+ common_cxx_options & common_fortran_options or something similar. We also
+ need to document the fortran specific fflags option. Possibly related Boost
+ Build code should be updated as well so that fortran options may not be
+ specified for non-fortran toolsets and C/C++ options may not be specified
+ for non-C/C++ ones. -->
+
<varlistentry>
<term><literal>cflags</literal></term>
-
- <listitem><para>Specifies additional compiler flags that
- will be used when compiling C sources.</para>
- </listitem>
+
+ <listitem><para>Specifies additional compiler flags that will be used when
+ compiling C sources.</para></listitem>
</varlistentry>
-
+
<varlistentry>
<term><literal>cxxflags</literal></term>
-
- <listitem><para>Specifies additional compiler flags that
- will be used when compiling C++ sources.</para>
- </listitem>
+
+ <listitem><para>Specifies additional compiler flags that will be used when
+ compiling C++ sources.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>compileflags</literal></term>
-
- <listitem><para>Specifies additional compiler flags that
- will be used when compiling both C and C++ sources.</para>
- </listitem>
+
+ <listitem><para>Specifies additional compiler flags that will be used when
+ compiling both C and C++ sources.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>linkflags</literal></term>
-
- <listitem><para>Specifies additional command line options
- that will be passed to the linker.</para>
+
+ <listitem><para>Specifies additional command line options that will be
+ passed to the linker.</para>
</listitem>
</varlistentry>
-
</section>
-
</chapter>
Modified: branches/release/tools/build/v2/doc/src/reference.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/reference.xml (original)
+++ branches/release/tools/build/v2/doc/src/reference.xml 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -150,16 +150,14 @@
<listitem>
<para>
- An argument containing either slashes or
- the <code>=</code> symbol specifies a number of build
- request elements (see <xref
- linkend="bbv2.advanced.build_request"/>). In its simplest
- form, it's just a set of properties, separated by
- slashes, which become a single build request element,
- for example:
+ An argument containing either slashes or the <code>=</code> symbol
+ specifies a number of build request elements (see <xref linkend=
+ "bbv2.advanced.build_request"/>). In its simplest form, it is just
+ a set of properties, separated by slashes, which become a single
+ build request element, for example:
<programlisting>
-borland/<runtime-link>static
+borland/runtime-link=static
</programlisting>
A more complex form can be used to save typing. For example,
@@ -184,13 +182,13 @@
part should have either the form
<programlisting>
-<emphasis>feature-name</emphasis>=<emphasis>feature-value1</emphasis>[","<emphasis>feature-valueN</emphasis>]*
+<emphasis>feature-name</emphasis>=<emphasis>feature-value1</emphasis>[","<emphasis>feature-valueN</emphasis>]*
</programlisting>
or, in case of implicit features
<programlisting>
-<emphasis>feature-value1</emphasis>[","<emphasis>feature-valueN</emphasis>;]*
+<emphasis>feature-value1</emphasis>[","<emphasis>feature-valueN</emphasis>;]*
</programlisting>
will be converted into the property set
@@ -225,7 +223,7 @@
They are described in the following table.</para>
<para>FIXME: That table has moved into "User documentation" section
- and there's nothing we can add here. Remove this part?</para>
+ and there is nothing we can add here. Remove this part?</para>
</section>
@@ -244,36 +242,36 @@
<variablelist>
<varlistentry>
<term><literal>exe</literal></term>
-
- <listitem><para>Creates an executable file. See
+
+ <listitem><para>Creates an executable file. See
<xref linkend="bbv2.tasks.programs"/>.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>lib</literal></term>
-
- <listitem><para>Creates an library file. See
+
+ <listitem><para>Creates an library file. See
<xref linkend="bbv2.tasks.libraries"/>.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>install</literal></term>
-
- <listitem><para>Installs built targets and other files. See
+
+ <listitem><para>Installs built targets and other files. See
<xref linkend="bbv2.tasks.installing"/>.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>alias</literal></term>
-
- <listitem><para>Creates an alias for other targets. See
+
+ <listitem><para>Creates an alias for other targets. See
<xref linkend="bbv2.tasks.alias"/>.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>unit-test</literal></term>
-
- <listitem><para>Creates an executable that will be automatically run. See
+
+ <listitem><para>Creates an executable that will be automatically run. See
<xref linkend="bbv2.tutorial.testing"/>.</para></listitem>
</varlistentry>
@@ -284,23 +282,23 @@
<term><literal>link-fail</literal></term>
<term><literal>run</literal></term>
<term><literal>run-fail</literal></term>
-
- <listitem><para>Specialized rules for testing. See
+
+ <listitem><para>Specialized rules for testing. See
<xref linkend="bbv2.tutorial.testing"/>.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>obj</literal></term>
-
+
<listitem><para>Creates an object file. Useful when a single source
file must be compiled with special properties.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>glob</literal></term>
-
- <listitem><para>The <code>glob</code> rule takes a list shell pattern
+
+ <listitem><para>The <code>glob</code> rule takes a list shell pattern
and returns the list of files in the project's source directory that
match the pattern. For example:
<programlisting>
@@ -319,15 +317,15 @@
<varlistentry id="bbv2.reference.glob-tree">
<indexterm><primary>glob-tree</primary></indexterm>
<term><literal>glob-tree</literal></term>
-
+
<listitem><para>The <code>glob-tree</code> is similar to the
<code>glob</code> except that it operates recursively from
the directory of the containing Jamfile. For example:
<programlisting>
ECHO [ glob-tree *.cpp : .svn ] ;
</programlisting>
- will print the names of all C++ files in your project. The
- <literal>.svn</literal> exclude pattern prevents the
+ will print the names of all C++ files in your project. The
+ <literal>.svn</literal> exclude pattern prevents the
<code>glob-tree</code> rule from entering administrative
directories of the Subversion version control system.
</para></listitem>
@@ -335,7 +333,7 @@
<varlistentry>
<term><literal>project</literal></term>
-
+
<listitem><para>Declares project id and attributes, including
project requirements. See <xref linkend="bbv2.advanced.projects"/>.
</para></listitem>
@@ -343,15 +341,15 @@
<varlistentry>
<term><literal>use-project</literal></term>
-
- <listitem><para>Assigns a symbolic project ID to a project at
+
+ <listitem><para>Assigns a symbolic project ID to a project at
a given path. This rule must be better documented!
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>explicit</literal></term>
-
+
<listitem><para>The <literal>explicit</literal> rule takes a single
parameter—a list of target names. The named targets will
be marked explicit, and will be built only if they are explicitly
@@ -362,7 +360,7 @@
<varlistentry>
<term><literal>constant</literal></term>
-
+
<listitem><para>Sets project-wide constant. Takes two
parameters: variable name and a value and makes the specified
variable name accessible in this Jamfile and any child Jamfiles.
@@ -375,7 +373,7 @@
<varlistentry>
<term><literal>path-constant</literal></term>
-
+
<listitem><para>Same as <literal>constant</literal> except that
the value is treated as path relative to Jamfile location. For example,
if <command>bjam</command> is invoked in the current directory,
@@ -383,17 +381,17 @@
<programlisting>
path-constant DATA : data/a.txt ;
</programlisting>
- then the variable <varname>DATA</varname> will be set to
+ then the variable <varname>DATA</varname> will be set to
<literal>helper/data/a.txt</literal>, and if <command>bjam</command>
is invoked from the <filename>helper</filename> directory, then
- the variable <varname>DATA</varname> will be set to
+ the variable <varname>DATA</varname> will be set to
<literal>data/a.txt</literal>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>build-project</literal></term>
-
+
<listitem><para>Cause some other project to be built. This rule
takes a single parameter—a directory name relative to
the containing Jamfile. When the containing Jamfile is built,
@@ -405,7 +403,7 @@
<varlistentry>
<term><literal>test-suite</literal></term>
-
+
<listitem><para>This rule is deprecated and equivalent to
<code>alias</code>.</para></listitem>
</varlistentry>
@@ -415,52 +413,52 @@
</section>
<section id="bbv2.advanced.builtins.features">
- <title>Builtin features</title>
-
+ <title>Builtin features</title>
+
<variablelist>
<varlistentry><term><literal>variant</literal></term>
-
+
<listitem>
<para>
A feature that combines several low-level features, making
it easy to request common build configurations.
</para>
-
+
<para><emphasis role="bold">Allowed values:</emphasis> <literal>debug</literal>, <literal>release</literal>,
<literal>profile</literal>.</para>
-
+
<para>The value <literal>debug</literal> expands to</para>
-
+
<programlisting>
<optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on
</programlisting>
-
+
<para>The value <literal>release</literal> expands to</para>
-
+
<programlisting>
<optimization>speed <debug-symbols>off <inlining>full <runtime-debugging>off
</programlisting>
-
+
<para>The value <literal>profile</literal> expands to the same as
<literal>release</literal>, plus:</para>
-
+
<programlisting>
<profiling>on <debug-symbols>on
</programlisting>
<para>User can define his own build variants using the <code>variant</code> rule from the <code>common</code>
module.</para>
-
+
<para><emphasis role="bold">Notee:</emphasis> Runtime
debugging is on in debug builds to suit the expectations of
- people used to various IDEs.
+ people used to various IDEs.
<!-- Define "runtime debugging." Why will those people expect it to be on in debug builds? -->
</para>
</listitem></varlistentry>
-
+
<varlistentry id="bbv2.advanced.builtins.features.link">
<term><literal>link</literal></term>
-
+
<listitem>
<para><emphasis role="bold">Allowed values:</emphasis> <literal>shared</literal>,
@@ -469,13 +467,13 @@
<simpara>
A feature that controls how libraries are built.
</simpara>
-
+
</listitem></varlistentry>
<varlistentry id="bbv2.advanced.builtins.features.runtime-link">
<indexterm><primary>runtime linking</primary></indexterm>
<term><literal>runtime-link</literal></term>
-
+
<listitem>
<para><emphasis role="bold">Allowed values:</emphasis> <literal>shared</literal>,
<literal>static</literal></para>
@@ -488,33 +486,33 @@
mixing static and shared runtime requires extreme care. Check
your compiler documentation for more details.
</simpara>
-
+
</listitem>
</varlistentry>
-
+
<varlistentry><term><literal>source</literal></term>
-
+
<listitem>
<simpara>
- The <code><source>X</code> feature has the same effect on
- building a target as putting X in the list of sources.
- It's useful when you want to add
- the same source to all targets in the project
+ The <code><source>X</code> feature has the same effect on
+ building a target as putting X in the list of sources. It is useful
+ when you want to add the same source to all targets in the project
(you can put <source> in requirements) or to conditionally
- include a source (using conditional requirements, see <xref linkend="bbv2.tutorial.conditions"/>)
- See also the <code><library></code> feature.
+ include a source (using conditional requirements, see <xref linkend=
+ "bbv2.tutorial.conditions"/>). See also the <code><library>
+ </code> feature.
</simpara>
</listitem>
</varlistentry>
-
+
<varlistentry><term><literal>library</literal></term>
-
+
<listitem>
<simpara>
- This feature is almost equivalent to the <code><source></code> feature,
- except that it takes effect only for linking. When you want to
- link all targets in a Jamfile to certain library, the
- <code><library></code> feature is preferred over
+ This feature is almost equivalent to the <code><source></code>
+ feature, except that it takes effect only for linking. When you want
+ to link all targets in a Jamfile to certain library, the
+ <code><library></code> feature is preferred over
<code><source>X</code> -- the latter will add the library to
all targets, even those that have nothing to do with libraries.
</simpara>
@@ -523,55 +521,65 @@
<varlistentry><term><anchor id="bbv2.builtin.features.dependency"/>
<literal>dependency</literal></term>
-
+
<listitem>
<simpara>
- Introduces a dependency on the target named by the
- value of this feature (so it will be brought
- up-to-date whenever the target being declared is).
- The dependency is not used in any other way. For example, in
- application with plugins, the plugins are not used when linking
- the application,
- application might have dependency on its plugins, even though
-
-
- , and
- adds its usage requirements to the build properties
- of the target being declared.
+ Introduces a dependency on the target named by the value of this
+ feature (so it will be brought up-to-date whenever the target being
+ declared is). The dependency is not used in any other way.
+
+ <!--
+ ====================================================================
+ An example and a motivation is needed here. Below is some commented
+ out content that used to be here but did not make any sense and
+ seems to have been left unfinished in some previous revision. Should
+ be fixed and this whole feature should be retested and fixed as
+ needed.
+ ====================================================================
+ For example, in application with plugins, the plugins are not used
+ when linking the application, application might have a dependency on
+ its plugins, even though
+
+ and
+ adds its usage requirements to the build properties
+ of the target being declared.
- The primary use case is when you want
+ The primary use case is when you want
the usage requirements (such as <code>#include</code> paths) of some
- library to be applied, but don't want to link to it.
- <!-- It's hard to picture why anyone would want to do
- that. Please flesh out this motivation -->
+ library to be applied, but do not want to link to it.
+
+ It is hard to picture why anyone would want to do that. Please flesh
+ out this motivation.
+ ====================================================================
+ -->
</simpara>
</listitem>
</varlistentry>
-
+
<varlistentry><term><anchor id="bbv2.builtin.features.use"/>
<literal>use</literal></term>
-
+
<listitem>
<simpara>
- Introduces a dependency on the target named by the
- value of this feature (so it will be brought
- up-to-date whenever the target being declared is), and
- adds its usage requirements to the build properties
+ Introduces a dependency on the target named by the value of this
+ feature (so it will be brought up-to-date whenever the target being
+ declared is), and adds its usage requirements to the build
+ properties
<!-- Do you really mean "to the requirements?" -->
- of the target being declared. The dependency is not used
- in any other way. The primary use case is when you want
- the usage requirements (such as <code>#include</code> paths) of some
- library to be applied, but don't want to link to it.
- <!-- It's hard to picture why anyone would want to do
- that. Please flesh out this motivation -->
+ of the target being declared. The dependency is not used in any
+ other way. The primary use case is when you want the usage
+ requirements (such as <code>#include</code> paths) of some library
+ to be applied, but do not want to link to it.
+ <!-- It is hard to picture why anyone would want to do that. Please
+ flesh out this motivation. -->
</simpara>
</listitem>
</varlistentry>
-
+
<varlistentry><term><anchor id="bbv2.reference.features.dll-path"/>
<literal>dll-path</literal></term>
-
+
<listitem>
<simpara>
Specify an additional directory where the system should
@@ -581,53 +589,51 @@
in <xref linkend="bbv2.faq"/> for details.
</simpara>
</listitem></varlistentry>
-
+
<varlistentry><term><literal>hardcode-dll-paths</literal></term>
-
+
<listitem>
<simpara>
Controls automatic generation of dll-path properties.
</simpara>
-
+
<para><emphasis role="bold">Allowed values:</emphasis>
- <literal>true</literal>, <literal>false</literal>. This property
- is specific to Unix systems. If an executable is built with
+ <literal>true</literal>, <literal>false</literal>. This property is
+ specific to Unix systems. If an executable is built with
<code><hardcode-dll-paths>true</code>, the generated binary
- will contain the list of all the paths to the used shared
- libraries. As the result, the executable can be run without
- changing system paths to shared libraries or installing the
- libraries to system paths. This
- <!-- you need an antecedent. This _what_? -->
- is very convenient during
- development. Plase see the <link
- linkend="bbv2.faq.dll-path">FAQ entry</link> for details.
- Note that on Mac OSX, the paths are unconditionally hardcoded by
- the linker, and it's not possible to disable that behaviour.
- </para>
- </listitem></varlistentry>
+ will contain the list of all the paths to the used shared libraries.
+ As the result, the executable can be run without changing system
+ paths to shared libraries or installing the libraries to system
+ paths. This <!-- you need an antecedent. This _what_? --> is very
+ convenient during development. Plase see the <link linkend=
+ "bbv2.faq.dll-path">FAQ entry</link> for details. Note that on Mac
+ OSX, the paths are unconditionally hardcoded by the linker, and it
+ is not possible to disable that behaviour.</para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><literal>cflags</literal></term>
<term><literal>cxxflags</literal></term>
<term><literal>linkflags</literal></term>
-
+
<listitem>
<simpara>
The value of those features is passed without modification to the
- corresponding tools. For <code>cflags</code> that's both the C and C++
- compilers, for <code>cxxflags</code> that's the C++ compiler and for
- <code>linkflags</code> that's the linker. The features are handy when
- you're trying to do something special that cannot be achieved by
- higher-level feature in Boost.Build.
+ corresponding tools. For <code>cflags</code> that is both the C and
+ C++ compilers, for <code>cxxflags</code> that is the C++ compiler
+ and for <code>linkflags</code> that is the linker. The features are
+ handy when you are trying to do something special that cannot be
+ achieved by a higher-level feature in Boost.Build.
</simpara>
</listitem>
</varlistentry>
<varlistentry><term><literal>warnings</literal></term>
-
<listitem>
<simpara>
- The <code><warnings></code> feature controls the warning level of compilers. It has the following values:
+ The <code><warnings></code> feature controls the warning level
+ of compilers. It has the following values:
<itemizedlist>
<listitem><para><code>off</code> - disables all warnings.</para></listitem>
<listitem><para><code>on</code> - enables default warning level for the tool.</para></listitem>
@@ -639,25 +645,27 @@
</varlistentry>
<varlistentry><term><literal>warnings-as-errors</literal></term>
-
<listitem>
<simpara>
- The <code><warnings-as-errors></code> makes it possible to treat warnings as errors and abort
- compilation on a warning. The value <code>on</code> enables this behaviour. The default value is
+ The <code><warnings-as-errors></code> makes it possible to
+ treat warnings as errors and abort compilation on a warning. The
+ value <code>on</code> enables this behaviour. The default value is
<code>off</code>.
</simpara>
</listitem>
</varlistentry>
<varlistentry><term><literal>build</literal></term>
-
+
<listitem>
<para><emphasis role="bold">Allowed values:</emphasis> <literal>no</literal></para>
<para>
- The <code>build</code> feature is used to conditionally disable build of a target. If <code><build>no</code>
- is in properties when building a target, build of that target is skipped. Combined with conditional requirements this
- allows to skip building some target in configurations where the build is known to fail.
+ The <code>build</code> feature is used to conditionally disable
+ build of a target. If <code><build>no</code> is in properties
+ when building a target, build of that target is skipped. Combined
+ with conditional requirements this allows you to skip building some
+ target in configurations where the build is known to fail.
</para>
</listitem>
</varlistentry>
@@ -667,32 +675,31 @@
<listitem><para>The <literal>tag</literal> feature is used to customize
the name of the generated files. The value should have the form:
<programlisting>@<replaceable>rulename</replaceable></programlisting> where
- <replaceable>rulename</replaceable> should be a name of a rule with
- the following signature:
+ <replaceable>rulename</replaceable> should be a name of a rule with the
+ following signature:
<programlisting>rule tag ( name : type ? : property-set )</programlisting>
The rule will be called for each target with the default name computed
- by Boost.Build, the type of the target, and property set. The rule
- can either return a string that must be used as the name of the
- target, or empty string, in which case the default name will be used.
+ by Boost.Build, the type of the target, and property set. The rule can
+ either return a string that must be used as the name of the target, or
+ an empty string, in which case the default name will be used.
</para>
- <para>Most typical use of the <literal>tag</literal> feature is
- to encode build properties, or library version in library target names.
- You should take care to return non-empty string from the tag rule
- only for types you care about — otherwise, you might
- end up modifying names of object files, generated header file and
- other targets for which changing names does not make sense.</para>
+ <para>Most typical use of the <literal>tag</literal> feature is to
+ encode build properties, or library version in library target names. You
+ should take care to return non-empty string from the tag rule only for
+ types you care about — otherwise, you might end up modifying
+ names of object files, generated header file and other targets for which
+ changing names does not make sense.</para>
</listitem>
-
</varlistentry>
<varlistentry><term><literal>debug-symbols</literal></term>
-
- <listitem>
+
+ <listitem>
<para><emphasis role="bold">Allowed values:</emphasis> <literal>on</literal>, <literal>off</literal>.</para>
<para>The <literal>debug-symbols</literal> feature specifies if
- produced object files, executables and libraries should include
+ produced object files, executables and libraries should include
debug information.
Typically, the value of this feature is implicitly set by the
<literal>variant</literal> feature, but it can be explicitly
@@ -702,48 +709,48 @@
</varlistentry>
<varlistentry><term><literal>architecture</literal></term>
- <listitem>
+ <listitem>
<para>The <literal>architecture</literal> features specifies
the general processor familty to generate code for.</para>
-
+
</listitem>
</varlistentry>
<varlistentry><term><literal>instruction-set</literal></term>
<indexterm><primary>instruction-set</primary></indexterm>
- <listitem>
+ <listitem>
<para>Allowed values for this feature depend on used toolset.</para>
- <para>The <literal>instruction-set</literal> specifies for which
+ <para>The <literal>instruction-set</literal> specifies for which
specific instruction set the code should be generated. The
code in general might not run on processors with older/different
instruction sets.</para>
<para>While Boost.Build allows a large set of possible values
for this features, whether a given value works depends on which
- compiler you use. Please see
+ compiler you use. Please see
<xref linkend="bbv2.reference.tools.compilers"/> for details.
</para>
-
+
</listitem>
</varlistentry>
<varlistentry><term><literal>address-model</literal></term>
- <indexterm><primary>64-bit compilation</primary></indexterm>
- <listitem>
+ <indexterm><primary>64-bit compilation</primary></indexterm>
+ <listitem>
<para><emphasis role="bold">Allowed values:</emphasis> <literal>32</literal>, <literal>64</literal>.</para>
<para>The <literal>address-model</literal> specifies if 32-bit or
64-bit code should be generated by the compiler. Whether this feature
- works depends on the used compiler, it's version, how the compiler
- is configured, and the values of the <literal>architecture</literal>
+ works depends on the used compiler, its version, how the compiler is
+ configured, and the values of the <literal>architecture</literal>
<literal>instruction-set</literal>
- features. Please see <xref linkend="bbv2.reference.tools.compilers"/>
+ features. Please see <xref linkend="bbv2.reference.tools.compilers"/>
for details.</para>
</listitem>
</varlistentry>
-
+
</variablelist>
</section>
@@ -754,8 +761,8 @@
and other tools. This section documents how to use those tools.</para>
<para>Before using any tool, you must declare your intention, and possibly
- specify additional information about tool's configuration. This is done
- with the <code>using</code> rule, for example:
+ specify additional information about the tool's configuration. This is
+ done with the <code>using</code> rule, for example:
<programlisting>
using gcc ;
</programlisting>
@@ -776,9 +783,9 @@
<section id="bbv2.reference.tools.compiler.gcc">
<title>GNU C++</title>
-
- <para>The <code>gcc</code> module supports the
- <ulink url="http://gcc.gnu.org">GNU C++ compiler</ulink>
+
+ <para>The <code>gcc</code> module supports the
+ <ulink url="http://gcc.gnu.org">GNU C++ compiler</ulink>
on Linux, a number of Unix-like system including MacOS X, SunOS and
BeOS, and on Windows (either <ulink url="http://www.cygwin.com">Cygwin</ulink>
or <ulink url="http://www.mingw.org">MinGW</ulink>).
@@ -803,11 +810,11 @@
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
- <xi:include href="fragments.xml#xpointer(id('root_option')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('root_option')/*)"
+ parse="xml"/>
<varlistentry>
<term><literal>rc</literal></term>
@@ -830,7 +837,7 @@
or <code>rc</code> for borland's resource compiler.</para>
</listitem>
</varlistentry>
-
+
</variablelist>
<indexterm><primary>64-bit compilation</primary>
@@ -849,11 +856,12 @@
<title>Microsoft Visual C++</title>
- <para>The <code>msvc</code> module supports the
+ <para>The <code>msvc</code> module supports the
<ulink url="http://msdn.microsoft.com/visualc/">Microsoft Visual
C++</ulink> command-line tools on Microsoft Windows. The supported
products and versions of command line tools are listed below:</para>
<itemizedlist>
+ <listitem><para>Visual Studio 2008—9.0</para></listitem>
<listitem><para>Visual Studio 2005—8.0</para></listitem>
<listitem><para>Visual Studio .NET 2003—7.1</para></listitem>
<listitem><para>Visual Studio .NET—7.0</para></listitem>
@@ -867,12 +875,11 @@
</programlisting>
&using_repeation;
<para>If the version is not explicitly specified, the most recent
- version found in the registry will be used instead. If the
- special value <code>all</code> is passed as the version, all
- versions found in the registry will be configured. If a version is
- specified, but the command is not, the compiler binary will be
- searched in standard installation paths for that version, followed
- by <envar>PATH</envar>.
+ version found in the registry will be used instead. If the special
+ value <code>all</code> is passed as the version, all versions found in
+ the registry will be configured. If a version is specified, but the
+ command is not, the compiler binary will be searched in standard
+ installation paths for that version, followed by <envar>PATH</envar>.
</para>
<para>The compiler command should be specified using forward slashes,
@@ -881,84 +888,98 @@
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
<varlistentry>
- <term><literal>setup</literal></term>
+ <term><literal>assembler</literal></term>
- <listitem><para>The filename of the environment setup scripts
- to run before invoking the compiler. If not specified,
- <command>vcvars32.bat</command> alongside the compiler binary
- will be used.</para>
- </listitem>
+ <listitem><para>The command that compiles assembler sources. If
+ not specified, <command>ml</command> will be used. The command
+ will be invoked after the setup script was executed and adjusted
+ the <envar>PATH</envar> variable.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>compiler</literal></term>
- <listitem><para>The command that compiles C and C++ sources.
- If not specified, <command>cl</command> will be used. The
- command will be invoked after the setup script was
- executed and adjusted the <envar>PATH</envar> variable.</para>
- </listitem>
+ <listitem><para>The command that compiles C and C++ sources. If
+ not specified, <command>cl</command> will be used. The command
+ will be invoked after the setup script was executed and adjusted
+ the <envar>PATH</envar> variable.</para></listitem>
</varlistentry>
<varlistentry>
- <term><literal>linker</literal></term>
+ <term><literal>compiler-filter</literal></term>
- <listitem><para>The command that links executables and dynamic
- libraries.
- If not specified, <command>link</command> will be used. The
- command will be invoked after the setup script was
- executed and adjusted the <envar>PATH</envar> variable.</para>
- </listitem>
+ <listitem><para>Command through which to pipe the output of
+ running the compiler. For example to pass the output to STLfilt.
+ </para></listitem>
</varlistentry>
<varlistentry>
- <term><literal>assembler</literal></term>
+ <term><literal>idl-compiler</literal></term>
- <listitem><para>The command that compiles assember files.
- If not specified, <command>cl</command> will be used. The
- command will be invoked after the setup script was
+ <listitem><para>The command that compiles Microsoft COM interface
+ definition files. If not specified, <command>midl</command> will
+ be used. The command will be invoked after the setup script was
executed and adjusted the <envar>PATH</envar> variable.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>resource-compiler</literal></term>
+ <term><literal>linker</literal></term>
- <listitem><para>The command that compiles resource files.
- If not specified, <command>rc</command> will be used. The
- command will be invoked after the setup script was
- executed and adjusted the <envar>PATH</envar> variable.</para>
- </listitem>
+ <listitem><para>The command that links executables and dynamic
+ libraries. If not specified, <command>link</command> will be used.
+ The command will be invoked after the setup script was executed
+ and adjusted the <envar>PATH</envar> variable.</para></listitem>
</varlistentry>
<varlistentry>
- <term><literal>idl-compiler</literal></term>
+ <term><literal>mc-compiler</literal></term>
- <listitem><para>The command that compiles Microsoft COM
- interface definition files.
- If not specified, <command>midl</command> will be used. The
- command will be invoked after the setup script was
+ <listitem><para>The command that compiles Microsoft message
+ catalog files. If not specified, <command>mc</command> will be
+ used. The command will be invoked after the setup script was
executed and adjusted the <envar>PATH</envar> variable.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>mc-compiler</literal></term>
+ <term><literal>resource-compiler</literal></term>
- <listitem><para>The command that compiles Microsoft message
- catalog files.
- If not specified, <command>mt</command> will be used. The
- command will be invoked after the setup script was
- executed and adjusted the <envar>PATH</envar> variable.</para>
- </listitem>
+ <listitem><para>The command that compiles resource files. If not
+ specified, <command>rc</command> will be used. The command will be
+ invoked after the setup script was executed and adjusted the
+ <envar>PATH</envar> variable.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>setup</literal></term>
+
+ <listitem><para>The filename of the global environment setup
+ script to run before invoking any of the tools defined in this
+ toolset. Will not be used in case a target platform specific
+ script has been explicitly specified for the current target
+ platform. Used setup script will be passed the target platform
+ identifier (x86, x86_amd64, x86_ia64, amd64 or ia64) as a
+ arameter. If not specified a default script is chosen based on the
+ used compiler binary, e.g. <command>vcvars32.bat</command> or
+ <command>vsvars32.bat</command>.</para></listitem>
+ </varlistentry>
- </variablelist>
+ <varlistentry>
+ <term><literal>setup-amd64></literal></term>
+ <term><literal>setup-i386></literal></term>
+ <term><literal>setup-ia64></literal></term>
+
+ <listitem><para>The filename of the target platform specific
+ environment setup script to run before invoking any of the tools
+ defined in this toolset. If not specified the global environment
+ setup script is used.</para></listitem>
+ </varlistentry>
+ </variablelist>
<section>
<title>64-bit support</title>
@@ -966,13 +987,14 @@
<indexterm><primary>64-bit compilation</primary>
<secondary>Microsoft Visual Studio</secondary></indexterm>
- <para>Starting with version 8.0, Microsoft Visual Studio
- can generate binaries for 64-bit processor, both 64-bit
- flavours of x86 (codenamed AMD64/EM64T), and
- Itanium (codenamed IA64). In addition, compilers that are
- itself run in 64-bit mode, for better performance, are provided.
- The complete list of compiler configurations are as follows
- (we abbreviate AMD64/EM64T to just AMD64):</para>
+ <para>Starting with version 8.0, Microsoft Visual Studio can
+ generate binaries for 64-bit processor, both 64-bit flavours of x86
+ (codenamed AMD64/EM64T), and Itanium (codenamed IA64). In addition,
+ compilers that are itself run in 64-bit mode, for better
+ performance, are provided. The complete list of compiler
+ configurations are as follows (we abbreviate AMD64/EM64T to just
+ AMD64):</para>
+
<itemizedlist>
<listitem><para>32-bit x86 host, 32-bit x86 target</para>
</listitem>
@@ -986,20 +1008,19 @@
</listitem>
</itemizedlist>
<para>
- The 32-bit host compilers can be always used, even on 64-bit Windows.
- On the contrary, 64-bit host compilers require both 64-bit
+ The 32-bit host compilers can be always used, even on 64-bit
+ Windows. On the contrary, 64-bit host compilers require both 64-bit
host processor and 64-bit Windows, but can be faster. By default,
- only 32-bit host, 32-bit target compiler is installed, and additional
- compilers should be installed explicitly.
+ only 32-bit host, 32-bit target compiler is installed, and
+ additional compilers need to be installed explicitly.
</para>
<para>To use 64-bit compilation you should:</para>
<orderedlist>
- <listitem><para>Configure you compiler as usual. If you provide
- a path to the compiler explicitly, provide the path to the
- 32-bit compiler. If you try to specify the path to any of 64-bit
- compilers, configuration won't work.</para>
- </listitem>
+ <listitem><para>Configure you compiler as usual. If you provide a
+ path to the compiler explicitly, provide the path to the 32-bit
+ compiler. If you try to specify the path to any of 64-bit
+ compilers, configuration will not work.</para></listitem>
<listitem><para>When compiling, use <code>address-model=64</code>,
to generate AMD64 code.</para></listitem>
@@ -1008,22 +1029,19 @@
<code>architecture=ia64</code></para></listitem>
</orderedlist>
- <para>The (AMD64 host, AMD64 target) compiler will be used
- automatically when you're generating AMD64 code and are
- running 64-bit Windows on AMD64. The (IA64 host, IA64 target)
- compiler won't be ever used, since nobody has an IA64 machine
- to test.</para>
+ <para>The (AMD64 host, AMD64 target) compiler will be used
+ automatically when you are generating AMD64 code and are running
+ 64-bit Windows on AMD64. The (IA64 host, IA64 target) compiler will
+ never be used, since nobody has an IA64 machine to test.</para>
<para>It is believed that AMD64 and EM64T targets are essentially
- compatible. The compiler options <code>/favor:AMD64</code>
- and <code>/favor:EM64T</code>, which are accepted only by
- AMD64 targeting compilers, cause the generated code to be
- tuned to a specific flavor of 64-bit x86. Boost.Build will
- make use of those options depending on the value
- of the<code>instruction-set</code> feature.</para>
-
+ compatible. The compiler options <code>/favor:AMD64</code> and
+ <code>/favor:EM64T</code>, which are accepted only by AMD64
+ targeting compilers, cause the generated code to be tuned to a
+ specific flavor of 64-bit x86. Boost.Build will make use of those
+ options depending on the value of the<code>instruction-set</code>
+ feature.</para>
</section>
-
</section>
<section id="bbv2.reference.tools.compiler.intel">
@@ -1052,25 +1070,25 @@
look in <envar>PATH</envar> for an executable <command>icpc</command>
(on Linux), or <command>icc.exe</command> (on Windows).
</para>
-
+
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
</variablelist>
-
+
<para>The Linux version supports the following additional options:</para>
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('root_option')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('root_option')/*)"
+ parse="xml"/>
</variablelist>
<!-- the compatibility option appears to be messed up -->
-
+
</section>
<section id="bbv2.reference.tools.compiler.acc">
@@ -1095,10 +1113,10 @@
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
</variablelist>
-
+
</section>
<section id="bbv2.reference.tools.compiler.borland">
@@ -1130,10 +1148,10 @@
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
</variablelist>
-
+
</section>
<section id="bbv2.reference.tools.compiler.como">
@@ -1141,7 +1159,7 @@
<title>Comeau C/C++ Compiler</title>
<para>The <code>como-linux</code> and the <code>como-win</code>
- modules supports the
+ modules supports the
<ulink url="http://www.comeaucomputing.com/">Comeau C/C++ Compiler</ulink>
on Linux and Windows respectively.</para>
@@ -1152,21 +1170,20 @@
&using_repeation;
<para>If the command is not specified, Boost.Build will search for
- a binary named <command>como</command> in
+ a binary named <command>como</command> in
<envar>PATH</envar>.</para>
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
</variablelist>
- <para>Before using the windows version of the compiler,
- you need to setup necessary environment variables per compiler's
- documentation. In particular, the <envar>COMO_XXX_INCLUDE</envar>
- variable should be set, where <envar>XXX</envar> corresponds to the
- used backend C compiler.</para>
-
+ <para>Before using the Windows version of the compiler, you need to
+ setup necessary environment variables per compiler's documentation. In
+ particular, the <envar>COMO_XXX_INCLUDE</envar> variable should be
+ set, where <envar>XXX</envar> corresponds to the used backend C
+ compiler.</para>
</section>
<section id="bbv2.reference.tools.compiler.cw">
@@ -1174,11 +1191,11 @@
<title>Code Warrior</title>
<para>The <code>cw</code> module support CodeWarrior compiler,
- originally produced by Metrowerks and presently developed
- by Freescale. Boost.Build supports only the versions of the compiler
- that target x86 processors. All such versions were released by
- Metrowerks before aquisition and are not sold any longer.
- The last version known to work is 9.4</para>
+ originally produced by Metrowerks and presently developed by
+ Freescale. Boost.Build supports only the versions of the compiler that
+ target x86 processors. All such versions were released by Metrowerks
+ before aquisition and are not sold any longer. The last version known
+ to work is 9.4.</para>
<para>The module is initialized using the following syntax:</para>
<programlisting>
@@ -1186,24 +1203,24 @@
&using_repeation;
- <para>If the command is not specified, Boost.Build will search for
- a binary named <command>mwcc</command> in default installation
- paths and in <envar>PATH</envar>.</para>
+ <para>If the command is not specified, Boost.Build will search for a
+ binary named <command>mwcc</command> in default installation paths and
+ in <envar>PATH</envar>.</para>
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
- <xi:include href="fragments.xml#xpointer(id('root_option')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('root_option')/*)"
+ parse="xml"/>
<varlistentry>
<term><literal>setup</literal></term>
<listitem><para>The command that sets up environment variables
- prior to invoking the compiler. If not specified,
+ prior to invoking the compiler. If not specified,
<command>cwenv.bat</command> alongside the compiler binary
will be used.</para>
</listitem>
@@ -1230,9 +1247,9 @@
executed and adjusted the <envar>PATH</envar> variable.</para>
</listitem>
</varlistentry>
-
+
</variablelist>
-
+
</section>
<section id="bbv2.reference.tools.compiler.dmc">
@@ -1250,15 +1267,15 @@
&using_repeation;
<para>If the command is not specified, Boost.Build will search for
- a binary named <command>como</command> in
+ a binary named <command>como</command> in
<envar>PATH</envar>.</para>
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
</variablelist>
-
+
</section>
<section id="bbv2.reference.tools.compiler.hp_cxx">
@@ -1280,10 +1297,10 @@
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
</variablelist>
-
+
</section>
<section id="bbv2.reference.tools.compiler.sun">
@@ -1302,7 +1319,7 @@
<para>If the command is not specified, Boost.Build will search for
a binary named <command>CC</command>
- in <filename>/opt/SUNWspro/bin</filename> and in
+ in <filename>/opt/SUNWspro/bin</filename> and in
<envar>PATH</envar>.</para>
<para>When using this compiler on complex C++ code, such as the
@@ -1316,15 +1333,15 @@
&option_list_intro;
<variablelist>
- <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
- parse="xml"/>
+ <xi:include href="fragments.xml#xpointer(id('common_options')/*)"
+ parse="xml"/>
</variablelist>
<indexterm><primary>64-bit compilation</primary>
<secondary>Sun Studio</secondary></indexterm>
Starting with Sun Studio 12, you can create 64-bit applications
by using the <code>address-model=64</code> property.
-
+
</section>
<section id="bbv2.reference.tools.compiler.vacpp">
@@ -1346,14 +1363,14 @@
<para>Later versions of Visual Age are known as XL C/C++. They
were not tested with the the <code>vacpp</code> module.</para>
-
+
</section>
</section>
<section>
<title>Third-party libraries</title>
-
+
<para>Boost.Build provides special support for some
third-party C++ libraries, documented below.</para>
@@ -1363,18 +1380,18 @@
<para>The <ulink url="http://stlport.org">STLport</ulink> library
is an alternative implementation of C++ runtime library. Boost.Build
- supports using that library on Windows platfrom. Linux is
+ supports using that library on Windows platfrom. Linux is
hampered by different naming of libraries in each STLport
version and is not officially supported.</para>
- <para>Before using STLport, you need to configure it in
+ <para>Before using STLport, you need to configure it in
<filename>user-config.jam</filename> using the following syntax:
</para>
<programlisting>
using stlport : <optional><replaceable>version</replaceable></optional> : <replaceable>header-path</replaceable> : <optional><replaceable>library-path</replaceable></optional> ;
</programlisting>
<para>
- Where <replaceable>version</replaceable> is the version of
+ Where <replaceable>version</replaceable> is the version of
STLport, for example <literal>5.1.4</literal>,
<replaceable>headers</replaceable> is the location where
STLport headers can be found, and <replaceable>libraries</replaceable>
@@ -1392,13 +1409,13 @@
</section>
</section>
-
+
</section>
<section id="bbv2.reference.buildprocess">
<title>Build process</title>
- <para>The general overview of the build process was given in the
+ <para>The general overview of the build process was given in the
<link linkend="bbv2.advanced.build_process">user documentation</link>.
This section provides additional details, and some specific rules.
</para>
@@ -1432,7 +1449,7 @@
<para>When there are several alternatives, one of them must be
selected. The process is as follows:</para>
-
+
<orderedlist>
<listitem>
<simpara>
@@ -1442,14 +1459,14 @@
requirements].
</simpara>
</listitem>
-
+
<listitem>
<simpara>
An alternative is viable only if all properties in condition
are present in build request.
</simpara>
</listitem>
-
+
<listitem>
<simpara>
If there's one viable alternative, it's choosen. Otherwise,
@@ -1462,8 +1479,8 @@
</simpara>
</listitem>
</orderedlist>
-
- </section>
+
+ </section>
<section id="bbv2.reference.buildprocess.common">
<title>Determining common properties</title>
@@ -1484,7 +1501,7 @@
<listitem><para>A non-conditional property in requirement in always
present in common properties.</para></listitem>
-
+
<listitem><para>A property in build request is present in
common properties, unless (2) tells otherwise.</para></listitem>
@@ -1511,14 +1528,14 @@
conditional property. For example, the following example works as
expected:
<programlisting>
-exe a : a.cpp
- : <toolset>gcc:<variant>release
+exe a : a.cpp
+ : <toolset>gcc:<variant>release
<variant>release:<define>FOO ;
</programlisting>
- </para>
+ </para>
</section>
-
+
</section>
@@ -1534,7 +1551,7 @@
aspect of a build configuration, such as whether inlining is
enabled. Feature names may not contain the '<literal>></literal>'
character.</para>
-
+
<!--
And what about dash?
-->
@@ -1544,7 +1561,7 @@
may not contain the '<literal><</literal>', '<literal>:</literal>', or
'<literal>=</literal>' characters. Feature values for free features may not
contain the '<literal><</literal>' character.</para>
-
+
<para>A <emphasis>property</emphasis> is a (feature,value) pair, expressed as
<feature>value.</para>
@@ -1553,7 +1570,7 @@
(in the context of its parent) from its value. A subfeature's
parent can never be another subfeature. Thus, features and their
subfeatures form a two-level hierarchy.</para>
-
+
<para>A <emphasis>value-string</emphasis> for a feature <emphasis role="bold">F</emphasis> is a string of
the form
<literal>value-subvalue1-subvalue2</literal>...<literal>-subvalueN</literal>, where
@@ -1563,22 +1580,22 @@
<literal><toolset>gcc <toolset-version>3.0.1</literal> can be
expressed more conscisely using a value-string, as
<literal><toolset>gcc-3.0.1</literal>.</para>
-
+
<para>A <emphasis>property set</emphasis> is a set of properties (i.e. a
collection without duplicates), for instance:
<literal><toolset>gcc <runtime-link>static</literal>.</para>
-
+
<para>A <emphasis>property path</emphasis> is a property set whose elements have
been joined into a single string separated by slashes. A property
path representation of the previous example would be
<literal><toolset>gcc/<runtime-link>static</literal>.</para>
-
+
<para>A <emphasis>build specification</emphasis> is a property set that fully
describes the set of features used to build a target.</para>
-
+
<section id="bbv2.reference.features.validity">
<title>Property Validity</title>
-
+
<para>
For <link linkend=
"bbv2.reference.features.attributes.free">free</link>
@@ -1592,11 +1609,11 @@
property is only valid in the presence of
<code><gcc-version>2.95.2</code>.
</para>
-
+
</section>
<section id="bbv2.reference.features.attributes">
<title>Feature Attributes</title>
-
+
<para>Each feature has a collection of zero or more of the following
attributes. Feature attributes are low-level descriptions of how the
build system should interpret a feature's values when they appear in
@@ -1604,31 +1621,31 @@
that an <emphasis>incidental</emphasis> property, for example, is
one whose feature has the <emphasis>incidental</emphasis>
attribute.</para>
-
+
<itemizedlist>
<listitem>
<para><emphasis>incidental</emphasis></para>
-
+
<para>Incidental features are assumed not to affect build
products at all. As a consequence, the build system may use
the same file for targets whose build specification differs
only in incidental features. A feature that controls a
compiler's warning level is one example of a likely
incidental feature.</para>
-
+
<para>Non-incidental features are assumed to affect build
products, so the files for targets whose build specification
differs in non-incidental features are placed in different
directories as described in "target paths" below. [ where? ]
</para>
</listitem>
-
+
<listitem>
<para>
<anchor id="bbv2.reference.features.attributes.propagated"/>
<emphasis>propagated</emphasis>
</para>
-
+
<para>Features of this kind are
propagated to dependencies. That is, if a <link linkend=
"bbv2.advanced.targets.main">main target</link> is built using a
@@ -1640,29 +1657,29 @@
libraries. Thus, the <literal><optimization></literal> feature is
propagated.</para>
</listitem>
-
+
<listitem>
<para>
<anchor id="bbv2.reference.features.attributes.free"/>
<emphasis>free</emphasis>
</para>
-
+
<para>Most features have a finite set of allowed values, and can
only take on a single value from that set in a given build
specification. Free features, on the other hand, can have
several values at a time and each value can be an arbitrary
string. For example, it is possible to have several
preprocessor symbols defined simultaneously:</para>
-
+
<programlisting>
<define>NDEBUG=1 <define>HAS_CONFIG_H=1
</programlisting>
</listitem>
-
+
<listitem>
<para><emphasis>optional</emphasis></para>
-
+
<para>An optional feature is a feature that is not required to
appear in a build specification. Every non-optional non-free
feature has a default value that is used when a value for
@@ -1742,25 +1759,25 @@
</section>
<section id="bbv2.reference.features.declaration">
<title>Feature Declaration</title>
-
+
<para>The low-level feature declaration interface is the
<literal>feature</literal> rule from the
<literal>feature</literal> module:
-
+
<programlisting>
rule feature ( name : allowed-values * : attributes * )
</programlisting>
-
+
A feature's allowed-values may be extended with the
<code>feature.extend</code> rule.
</para>
-
+
</section>
</section>
<section id="bbv2.reference.variants">
<title>Build Variants</title>
-
+
<para>
A build variant, or (simply variant) is a special kind of composite
feature that automatically incorporates the default values of
@@ -1783,7 +1800,7 @@
target requires some set of properties, it is needed to find the
set of properties to use for building. This process is called
<emphasis>property refinement</emphasis> and is performed by these rules</para>
-
+
<orderedlist>
<listitem>
@@ -1835,22 +1852,22 @@
<section id="bbv2.reference.ids">
<title>Target identifiers and references</title>
-
+
<para><emphasis>Target identifier</emphasis> is used to denote a
target. The syntax is:</para>
<programlisting>
target-id -> (project-id | target-name | file-name )
- | (project-id | directory-name) "//" target-name
+ | (project-id | directory-name) "//" target-name
project-id -> path
target-name -> path
file-name -> path
-directory-name -> path
+directory-name -> path
</programlisting>
<para>
This grammar allows some elements to be recognized as either
-
+
<itemizedlist>
<listitem>
<simpara>
@@ -1898,7 +1915,7 @@
<listitem>
<simpara>
- It allows to have main target names with slashes.
+ It allows to have main target names with slashes.
<!-- The motivation for which is:
@@ -1913,7 +1930,7 @@
target name that contains slashes?
3. Using sub-Jamfile in "foo" to declare extracted file "foo/b" is
- not an option, because you should not change existing tree
+ not an option, because you should not change existing tree
That makes good rationale for why main target must contain names.
-->
@@ -1937,21 +1954,21 @@
<programlisting>
exe compiler : compiler.cpp libs/cmdline/<optimization>space ;
</programlisting>
-
+
would cause the version of <literal>cmdline</literal> library,
optimized for space, to be linked in even if the
<literal>compiler</literal> executable is build with optimization for
speed.
</para>
</section>
-
+
</section>
<section id="bbv2.reference.generators">
<title>Generators</title>
<warning><para>The information is this section is likely to be outdated
- and misleading.
+ and misleading.
</para></warning>
<para>To construct a main target with given properties from sources,
@@ -1999,7 +2016,7 @@
</simpara>
</listitem>
</orderedlist>
-
+
<para>
Generator's required and optional properties may not include
either free or incidental properties. (Allowing this would
@@ -2126,7 +2143,7 @@
<!--
Local Variables:
mode: xml
- sgml-indent-data: t
+ sgml-indent-data: t
sgml-parent-document: ("userman.xml" "chapter")
sgml-set-face: t
End:
Modified: branches/release/tools/build/v2/doc/src/tasks.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/tasks.xml (original)
+++ branches/release/tools/build/v2/doc/src/tasks.xml 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -10,21 +10,20 @@
<title>Common tasks</title>
<para>This section describes main targets types that Boost.Build supports
- of-of-the-box. Unless otherwise noted, all mentioned main target rules
- have the common signature, described in <xref
- linkend="bbv2.advanced.targets"/>.
+ out-of-the-box. Unless otherwise noted, all mentioned main target rules have
+ the common signature, described in <xref linkend="bbv2.advanced.targets"/>.
</para>
-
+
<section id="bbv2.tasks.programs">
<title>Programs</title>
<indexterm><primary>exe</primary></indexterm>
- <para>Programs are created using the <code>exe</code> rule, which
- follows the <link linkend="bbv2.main-target-rule-syntax">common
- syntax</link>. For example:
+ <para>Programs are created using the <code>exe</code> rule, which follows
+ the <link linkend="bbv2.main-target-rule-syntax">common syntax</link>.
+ For example:
<programlisting>
-exe hello : hello.cpp some_library.lib /some_project//library
- : <threading>multi
+exe hello : hello.cpp some_library.lib /some_project//library
+ : <threading>multi
;
</programlisting>
This will create an executable file from the sources -- in this case,
@@ -35,7 +34,7 @@
</para>
<tip>
- <para>
+ <para>
On Windows, if an application uses dynamic libraries, and both
the application and the libraries are built by Boost.Build, its not
possible to immediately run the application, because the
@@ -44,9 +43,9 @@
manually, or place the application and the libraries to the same
directory. See <xref linkend="bbv2.tasks.installing"/>.
</para>
- <!-- We should be emphasizing the use of the built-in testing
- rules rather than continually discussing these quirks of
- running programs with dynamic libraries. -->
+ <!-- We should be emphasizing the use of the built-in testing rules
+ rather than continually discussing these quirks of running programs
+ with dynamic libraries. -->
</tip>
</section>
@@ -55,27 +54,27 @@
<para>Libraries are created using the <code>lib</code> rule, which
follows the <link linkend="bbv2.main-target-rule-syntax">common
- syntax</link>. For example:
+ syntax</link>. For example:
<programlisting>
lib helpers : helpers.cpp : <include>boost : : <include>. ;
</programlisting>
</para>
<!-- Add one sentence that says what the above does. -->
- <para>In the most common case, the <code>lib</code> creates a library
- from the specified sources. Depending on the value of
- <link> feature the library will be either static or
- shared. There are two other cases. First is when the library is
- installed somewhere in compiler's search paths, and should be
- searched by the compiler (typically, using the <option>-l</option>
- option). The second case is where the library is available as a
- prebuilt file and the full path is known.
+ <para>
+ In the most common case, the <code>lib</code> creates a library from the
+ specified sources. Depending on the value of <link> feature the
+ library will be either static or shared. There are two other cases.
+ First is when the library is installed somewhere in compiler's search
+ paths, and should be searched by the compiler (typically, using the
+ <option>-l</option> option). The second case is where the library is
+ available as a prebuilt file and the full path is known.
<!-- But the first case is also prebuilt. This is confusingly phrased. -->
- </para>
-
+ </para>
+
<para>
The syntax for these case is given below:
<programlisting>
-lib z : : <name>z <search>/home/ghost ;
+lib z : : <name>z <search>/home/ghost ;
lib compress : : <file>/opt/libs/compress.a ;
</programlisting>
The <code>name</code> property specifies the name that should be
@@ -106,7 +105,7 @@
release or debug versions.
<!-- explain -->
</para>
-
+
<para>
For convenience, the following syntax is allowed:
<programlisting>
@@ -115,18 +114,19 @@
</programlisting>
and is does exactly the same as:
<programlisting>
-lib z : : <name>z ;
-lib gui : : <name>gui ;
-lib db : : <name>db ;
-lib aux : : <name>aux ;
+lib z : : <name>z ;
+lib gui : : <name>gui ;
+lib db : : <name>db ;
+lib aux : : <name>aux ;
</programlisting>
</para>
-
- <para>When a library uses another library you should put that other
- library in the list of sources. This will do the right thing in all
- cases. For portability, you should specify library dependencies even
- for searched and prebuilt libraries, othewise, static linking on
- Unix won't work. For example:
+
+ <para>
+ When a library uses another library you should put that other library in
+ the list of sources. This will do the right thing in all cases. For
+ portability, you should specify library dependencies even for searched
+ and prebuilt libraries, othewise, static linking on Unix will not work.
+ For example:
<programlisting>
lib z ;
lib png : z : <name>png ;
@@ -134,15 +134,16 @@
</para>
<note>
- <para>When a library (say, <code>a</code>), that has another
- library, (say, <code>b</code>)
+ <para>
+ When a library (say, <code>a</code>), that has another library, (say,
+ <code>b</code>)
<!-- how can a library "have" a library? -->
is linked dynamically, the <code>b</code>
- library will be incorporated
+ library will be incorporated
<!-- Incorporated? Be precise. -->
in <code>a</code>. (If <code>b</code>
- is dynamic library as well, then <code>a</code> will only refer to
- it, and not include any extra code.)
+ is dynamic library as well, then <code>a</code> will only refer to it,
+ and not include any extra code.)
<!-- Don't parenthesize a whole sentence. -->
When the <code>a</code>
library is linked statically, Boost.Build will assure that all
@@ -150,9 +151,10 @@
<code>b</code>.
</para>
</note>
-
- <para>One feature of Boost.Build that is very important for libraries
- is usage requirements.
+
+ <para>
+ One feature of Boost.Build that is very important for libraries is usage
+ requirements.
<!-- Rephrase that. But then, it's much too late for an
introduction of usage requirements - you've already
discussed them many times. -->
@@ -161,7 +163,7 @@
lib helpers : helpers.cpp : : : <include>. ;
</programlisting>
then the compiler include path for all targets that use
- <code>helpers</code> will contain the directory
+ <code>helpers</code> will contain the directory
<!-- The rest of this sentence is unintelligible -->
where the target is defined.path to "helpers.cpp". The user
only needs to add <code>helpers</code> to the list of sources,
@@ -185,7 +187,7 @@
<code>a</code> library won't even refer to <code>b</code>.
</para>
</note>
-
+
</section>
<section id="bbv2.tasks.alias">
@@ -213,13 +215,13 @@
alias threads : /boost/thread//boost_thread : <link>static ;
</programlisting>
and use only the <code>threads</code> alias in your Jamfiles.
- </para>
+ </para>
<para>
You can also specify usage requirements for the
<code>alias</code> target. If you write the following:
<programlisting>
-alias header_only_library : : : : <include>/usr/include/header_only_library ;
+alias header_only_library : : : : <include>/usr/include/header_only_library ;
</programlisting>
then using <code>header_only_library</code> in sources will only add an
include path. Also note that when an alias has sources, their usage
@@ -233,7 +235,7 @@
will compile <filename>main.cpp</filename> with additional includes
required for using the specified static libraries.
</para>
-
+
</section>
<section id="bbv2.tasks.installing">
@@ -270,19 +272,19 @@
install dist : hello helpers : <variant>release:<location>dist/release
<variant>debug:<location>dist/debug ;
install dist2 : hello helpers : <location>$(DIST) ;
-</programlisting>
+</programlisting>
See also <link linkend="bbv2.reference.variants.propcond">conditional
properties</link> and <link linkend="bbv2.faq.envar">environment variables</link>
</para>
<bridgehead>Installing with all dependencies</bridgehead>
-
+
<para>
Specifying the names of all libraries to install can be boring. The
<code>install</code> allows you to specify only the top-level executable
targets to install, and automatically install all dependencies:
<programlisting>
-install dist : hello
+install dist : hello
: <install-dependencies>on <install-type>EXE
<install-type>LIB
;
@@ -304,16 +306,16 @@
<indexterm><primary>install-source-root</primary></indexterm>
<para>By default, the <code>install</code> rules will stip paths from
it's sources. So, if sources include <filename>a/b/c.hpp</filename>,
- the <filename>a/b</filename> part will be ignored. To make the
+ the <filename>a/b</filename> part will be ignored. To make the
<code>install</code> rule preserve the directory hierarchy you need
to use the <code>install-source-root</code> feature to specify the
root of the hierarchy you are installing. Relative paths from that
root will be preserved. For example, if you write:
<programlisting>
-install headers
- : a/b/c.h
- : <location>/tmp <install-source-root>a
+install headers
+ : a/b/c.h
+ : <location>/tmp <install-source-root>a
;
</programlisting>
@@ -323,7 +325,7 @@
<para>The <link linkend="bbv2.reference.glob-tree">glob-tree</link> rule
can be used to find all files below a given directory, making
it easy to install entire directory tree.</para>
-
+
<bridgehead>Installing into Several Directories</bridgehead>
<para>The <link linkend="bbv2.tasks.alias"><code>alias</code></link>
@@ -336,26 +338,26 @@
</programlisting>
</para>
- <para>Because the <code>install</code> rule just copies targets, most
- free features <footnote><para>see the definition of "free" in <xref
- linkend="bbv2.reference.features.attributes"/>.</para></footnote>
- have no effect when used in requirements of the <code>install</code> rule.
- The only two which matter are
- <link linkend="bbv2.builtin.features.dependency">
- <varname>dependency</varname></link> and, on Unix,
- <link linkend="bbv2.reference.features.dll-path"><varname>dll-path</varname></link>.
+ <para>
+ Because the <code>install</code> rule just copies targets, most free
+ features <footnote><para>see the definition of "free" in
+ <xref linkend="bbv2.reference.features.attributes"/>.</para></footnote>
+ have no effect when used in requirements of the <code>install</code> rule.
+ The only two which matter are <link
+ linkend="bbv2.builtin.features.dependency"><varname>dependency</varname>
+ </link> and, on Unix, <link linkend="bbv2.reference.features.dll-path">
+ <varname>dll-path</varname></link>.
</para>
<note>
<para>
(Unix specific). On Unix, executables built with Boost.Build typically
- contain the list of paths to all used dynamic libraries. For
- installing, this is not desired, so Boost.Build relinks the executable
- with an empty list of paths. You can also specify additional paths for
- installed executables with the <varname>dll-path</varname> feature.
+ contain the list of paths to all used dynamic libraries. For installing,
+ this is not desired, so Boost.Build relinks the executable with an empty
+ list of paths. You can also specify additional paths for installed
+ executables with the <varname>dll-path</varname> feature.
</para>
</note>
-
</section>
@@ -363,9 +365,10 @@
<title>Testing</title>
- <para>Boost.Build has convenient support for running unit tests. The
- simplest way is the <code>unit-test</code> rule, which follows the
- <link linkend="bbv2.main-target-rule-syntax">common syntax</link>. For
+ <para>
+ Boost.Build has convenient support for running unit tests. The simplest
+ way is the <code>unit-test</code> rule, which follows the <link
+ linkend="bbv2.main-target-rule-syntax">common syntax</link>. For
example:
<programlisting>
unit-test helpers_test : helpers_test.cpp helpers ;
@@ -380,22 +383,22 @@
can't miss a unit test failure.
</para>
- <para>By default, the executable is run directly. Sometimes, it's
+ <para>By default, the executable is run directly. Sometimes, it's
desirable to run the executable using some helper command. You should use the
<literal>testing.launcher</literal> property to specify the name of the
helper command. For example, if you write:
</para>
<programlisting>
-unit-test helpers_test
- : helpers_test.cpp helpers
+unit-test helpers_test
+ : helpers_test.cpp helpers
: <emphasis role="bold"><testing.launcher>valgrind</emphasis>
- ;
+ ;
</programlisting>
<para>The command used to run the executable will be:</para>
<screen>
-<emphasis role="bold">valgrind</emphasis> bin/$toolset/debug/helpers_test
+<emphasis role="bold">valgrind</emphasis> bin/$toolset/debug/helpers_test
</screen>
-
+
<para>There are few specialized testing rules, listed below:
<programlisting>
rule compile ( sources : requirements * : target-name ? )
@@ -403,7 +406,7 @@
rule link ( sources + : requirements * : target-name ? )
rule link-fail ( sources + : requirements * : target-name ? )
</programlisting>
- They are are given a list of sources and requirements.
+ They are are given a list of sources and requirements.
If the target name is not provided, the name of the first
source file is used instead. The <literal>compile*</literal>
tests try to compile the passed source. The <literal>link*</literal>
@@ -415,10 +418,10 @@
</para>
<para>There are two specialized rules for running applications, which
- are more powerful than the <code>unit-test</code> rule. The
+ are more powerful than the <code>unit-test</code> rule. The
<code>run</code> rule has the following signature:
<programlisting>
-rule run ( sources + : args * : input-files * : requirements * : target-name ?
+rule run ( sources + : args * : input-files * : requirements * : target-name ?
: default-build * )
</programlisting>
The rule builds application from the provided sources and runs it,
@@ -430,15 +433,15 @@
directory. The <code>run-fail</code> rule is identical to the
<code>run</code> rule, except that it expects that the run fails.
</para>
-
+
<para>All rules described in this section, if executed successfully,
create a special manifest file to indicate that the test passed.
For the <code>unit-test</code> rule the files is named
<filename><replaceable>target-name</replaceable>.passed</filename> and
- for the other rules it is called
+ for the other rules it is called
<filename><replaceable>target-name</replaceable>.test</filename>.
The <code>run*</code> rules also capture all output from the program,
- and store it in a file named
+ and store it in a file named
<filename><replaceable>target-name</replaceable>.output</filename>.</para>
<para>The <code>run</code> and the <code>run-fail</code> rules, if
@@ -451,12 +454,12 @@
the <literal>--dump-tests</literal> command-line option. The output
will consist of lines of the form:
<screen>
-boost-test(<replaceable>test-type</replaceable>) <replaceable>path</replaceable> : <replaceable>sources</replaceable>
- </screen>
+boost-test(<replaceable>test-type</replaceable>) <replaceable>path</replaceable> : <replaceable>sources</replaceable>
+ </screen>
</para>
<para>It is possible to process the list of tests, the output of
- bjam during command run, and the presense/absense of the
+ bjam during command run, and the presense/absense of the
<filename>*.test</filename> files created when test passes into
human-readable status table of tests. Such processing utilities
are not included in Boost.Build.</para>
@@ -467,53 +470,64 @@
<title>Custom commands</title>
- <para>When you use most of main target rules, Boost.Build automatically
- figures what commands to run and it what order. As soon as you want
- to use new file types, or support new tools, one approach is to
- extend Boost.Build to smoothly support them, as documented in
- <xref linkend="bbv2.extender"/>. However, if there's a single
- place where the new tool is used, it might be easier to just
- explicitly specify the commands to run.</para>
-
- <para>Three main target rules can be used for that. The
- <functionname>make</functionname> rule allows you to construct
- a single file from any number of source file, by running a
- command you specify. The <functionname>notfile</functionname> rule
- allows you to run an arbitrary command, without creating any files.
- Finaly, the <functionname>generate</functionname> rule allows you
- to describe transformation using Boost.Build's virtual targets.
- This is higher-level than file names that the make rule operates with,
- and allows you to create more than one target, or create differently
- named targets depending on properties, or use more than one
- tool.</para>
-
- <para>The <functionname>make</functionname> rule is used when you want to
- create one file from a number of sources using some specific command.
- The <functionname>notfile</functionname> is used to unconditionally run
- a command.
+ <para>
+ When you use most of main target rules, Boost.Build automatically
+ figures what commands to run and it what order. As soon as you want to
+ use new file types, or support new tools, one approach is to extend
+ Boost.Build to smoothly support them, as documented in
+ <xref linkend="bbv2.extender"/>. However, if there's a single place
+ where the new tool is used, it might be easier to just explicitly
+ specify the commands to run.
+ </para>
+
+ <para>
+ <!-- This paragraph requires links to where the terms 'virtual target'
+ & 'target' are defined. -->
+ Three main target rules can be used for that. The <functionname>make
+ </functionname> rule allows you to construct a single file from any
+ number of source file, by running a command you specify. The
+ <functionname>notfile</functionname> rule allows you to run an arbitrary
+ command, without creating any files. And finaly, the <functionname>
+ generate</functionname> rule allows you to describe transformation using
+ Boost.Build's virtual targets. This is higher-level than file names that
+ the <functionname>make</functionname> rule operates with and allows you
+ to create more than one target, create differently named targets
+ depending on properties or use more than one tool.
+ </para>
+
+ <para>
+ The <functionname>make</functionname> rule is used when you want to
+ create one file from a number of sources using some specific command.
+ The <functionname>notfile</functionname> is used to unconditionally run
+ a command.
</para>
+ <!-- We need to specify somewhere that the user can get rules like make,
+ notfile & generate defined in his Jamfiles by importing an appropriate
+ Boost.Build module. Also, each of those rules should get a separate
+ documentation page explicitly listing which module needs to be imported
+ for them to become accessible. -->
+
<para>
- Suppose you want to create file <filename>file.out</filename> from
- file <filename>file.in</filename> by running command
- <command>in2out</command>. Here's how you'd do this in Boost.Build:
+ Suppose you want to create file <filename>file.out</filename> from file
+ <filename>file.in</filename> by running command
+ <command>in2out</command>. Here is how you would do this in Boost.Build:
<programlisting>
+make file.out : file.in : @in2out ;
actions in2out
{
in2out $(<) $(>)
}
-make file.out : file.in : @in2out ;
</programlisting>
- If you run <command>bjam</command> and <filename>file.out</filename>
+ If you run <command>bjam</command> and <filename>file.out</filename>
does not exist, Boost.Build will run the <command>in2out</command>
- command to create that file. For more details on specifying actions,
- see <xref linkend="bbv2.advanced.jam_language.actions"/>.
+ command to create that file. For more details on specifying actions, see
+ <xref linkend="bbv2.advanced.jam_language.actions"/>.
</para>
-
<para>
- It could be that you just want to run some command unconditionally,
- and that command does not create any specific files. The, you can use
+ It could be that you just want to run some command unconditionally, and
+ that command does not create any specific files. For that you can use
the <functionname>notfile</functionname> rule. For example:
<programlisting>
notfile echo_something : @echo ;
@@ -527,97 +541,118 @@
Boost.Build will unconditionally run the action.
</para>
- <para>The <functionname>generate</functionname> rule is used when
- you want to express transformations using Boost.Build's virtual targets,
- as opposed to just filenames. The <functionname>generate</functionname>
- rule has the standard main target rule signature, but you are required
- to specify the <literal>generating-rule</literal> property. The value
- of the property should be in the form
- <literal>@<replaceable>rule-name</replaceable></literal> and the named
- rule should have the following signature:
- <programlisting>
+ <para>
+ <!-- This paragraph requires links to where terms like 'virtual target',
+ 'target', 'project-target' & 'property-set' are defined. -->
+ The <functionname>generate</functionname> rule is used when you want to
+ express transformations using Boost.Build's virtual targets, as opposed
+ to just filenames. The <functionname>generate</functionname> rule has
+ the standard main target rule signature, but you are required to specify
+ the <literal>generating-rule</literal> property. The value of the
+ property should be in the form
+ <literal>@<replaceable>rule-name</replaceable></literal>, the named rule
+ should have the following signature:
+<programlisting>
rule generating-rule ( project name : property-set : sources * )
- </programlisting>
- and will be called with an instance of the <code>project-target</code>
- class, the name of the main target, an instance of the
- <code>property-set</code> class containing build properties,
- and the list of instances of the <code>virtual-target</code> class
- corresponding to sources.
- The rule must return a list of <code>virtual-target</code> instances.
- The interface of the <code>virtual-target</code> class can be learned
- by looking at the <filename>build/virtual-target.jam</filename> file.
- The <filename>generate</filename> example in Boost.Build distribution
- illustrates how the <literal>generate</literal> rule can be used.
+</programlisting>
+ and will be called with an instance of the <code>project-target</code>
+ class, the name of the main target, an instance of the
+ <code>property-set</code> class containing build properties, and the
+ list of instances of the <code>virtual-target</code> class corresponding
+ to sources. The rule must return a list of <code>virtual-target</code>
+ instances. The interface of the <code>virtual-target</code> class can be
+ learned by looking at the <filename>build/virtual-target.jam</filename>
+ file. The <filename>generate</filename> example contained in the
+ Boost.Build distribution illustrates how the <literal>generate</literal>
+ rule can be used.
</para>
-
+
</section>
<section id="bbv2.reference.precompiled_headers">
<title>Precompiled Headers</title>
- <para>Precompiled headers is a mechanism to speed up compilation
- by creating a partially processed version of some header files,
- and then using that version during compilations rather then
- repeatedly parsing the original headers. Boost.Build supports
- precompiled headers with gcc and msvc toolsets.</para>
+ <para>
+ Precompiled headers is a mechanism to speed up compilation by creating a
+ partially processed version of some header files, and then using that
+ version during compilations rather then repeatedly parsing the original
+ headers. Boost.Build supports precompiled headers with gcc and msvc
+ toolsets.
+ </para>
+
+ <para>
+ To use precompiled headers, follow the following steps:
+ </para>
- <para>To use precompiled headers, follow these steps:</para>
<orderedlist>
- <listitem><para>Create a header that includes big headers used by your project.
- It's better to include only headers that are sufficiently stable —
- like headers from the compiler, and external libraries. Please wrap
- the header in <code>#ifdef BOOST_BUILD_PCH_ENABLED</code>, so that
- the potentially expensive inclusion of headers is not done
- when PCH is not enabled. Include the new header at the top of your
- source files.</para></listitem>
-
- <listitem><para>Declare a new Boost.Build target for the precompiled header
- and add that precompiled header to the sources of the target whose compilation
- you want to speed up:
- <programlisting>
-cpp-pch pch : pch.hpp ;
-exe main : main.cpp pch ;</programlisting>
- You can use the <code>c-pch</code> if you want to use the precompiled
- header in C programs.
+ <listitem><para>
+ Create a header that includes headers used by your project that you
+ want precompiled. It is better to include only headers that are
+ sufficiently stable — like headers from the compiler and
+ external libraries. Please wrap the header in <code>#ifdef
+ BOOST_BUILD_PCH_ENABLED</code>, so that the potentially expensive
+ inclusion of headers is not done when PCH is not enabled. Include the
+ new header at the top of your source files.
</para></listitem>
+ <listitem><para>
+ Declare a new Boost.Build target for the precompiled header and add
+ that precompiled header to the sources of the target whose compilation
+ you want to speed up:
+<programlisting>
+cpp-pch pch : pch.hpp ;
+exe main : main.cpp pch ;
+</programlisting>
+ You can use the <functionname>c-pch</functionname> rule if you want to
+ use the precompiled header in C programs.
+ </para></listitem>
</orderedlist>
- <para>The <filename>pch</filename> example in Boost.Build distribution
- can be used as reference.</para>
- <para>Please note the following:</para>
+ <para>
+ The <filename>pch</filename> example in Boost.Build distribution can be
+ used as reference.
+ </para>
+
+ <para>
+ Please note the following:
+ </para>
+
<itemizedlist>
- <listitem><para>The inclusion of the precompiled header must be the
- first thing in a source file, before any code or preprocessor directives.
+ <listitem><para>
+ The inclusion of the precompiled header must be the first thing in a
+ source file, before any code or preprocessor directives.
+ </para></listitem>
+
+ <listitem><para>
+ The build properties used to compile the source files and the
+ precompiled header must be the same. Consider using project
+ requirements to assure this.
</para></listitem>
- <listitem><para>The build properties used to compile the source files
- and the precompiled header must be the same. Consider using
- project requirements to assure this.
+ <listitem><para>
+ Precompiled headers must be used purely as a way to improve
+ compilation time, not to save the number of <code>#include</code>
+ statements. If a source file needs to include some header, explicitly
+ include it in the source file, even if the same header is included
+ from the precompiled header. This makes sure that your project will
+ build even if precompiled headers are not supported.
</para></listitem>
- <listitem><para>Precompiled headers must be used purely as a way to
- improve compilation time, not to save the number of <code>#include</code>
- statements. If a source file needs to include some header, explicitly include
- it in the source file, even if the same header is included from
- the precompiled header. This makes sure that your project will build
- even if precompiled headers are not supported.</para></listitem>
-
- <listitem><para>On the gcc compiler, the name of the header being
- precompiled must be equal to the name of the <code>cpp-pch</code>
- target. This is gcc requirement.</para></listitem>
-
- <listitem><para>Prior to version 4.2, the gcc compiler did not
- handle anonymous namespaces in precompiled headers, which
- limit their utility. See the <ulink url="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29085">bug
- report</ulink> for details.</para></listitem>
-
+ <listitem><para>
+ On the gcc compiler, the name of the header being precompiled must be
+ equal to the name of the <code>cpp-pch</code> target. This is a gcc
+ requirement.
+ </para></listitem>
+
+ <listitem><para>
+ Prior to version 4.2, the gcc compiler did not allow anonymous
+ namespaces in precompiled headers, which limits their utility. See the
+ <ulink url="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29085">bug
+ report</ulink> for details.
+ </para></listitem>
</itemizedlist>
-
-
</section>
-
<section id="bbv2.reference.generated_headers">
<title>Generated headers</title>
@@ -625,7 +660,7 @@
automatically. For example, for C++ files, all <literal>#include</literal>
statements are found and handled. The only aspect where user help
might be needed is implicit dependency on generated files.</para>
-
+
<para>By default, Boost.Build handles such dependencies within one
main target. For example, assume that main target "app" has two
sources, "app.cpp" and "parser.y". The latter source is converted
@@ -634,13 +669,13 @@
since "parser.h" will be generated into a build directory, the
path to that directory will automatically added to include
path.</para>
-
+
<para>Making this mechanism work across main target boundaries is
possible, but imposes certain overhead. For that reason, if
there's implicit dependency on files from other main targets, the
<literal><implicit-dependency></literal> [ link ] feature must
be used, for example:</para>
-
+
<programlisting>
lib parser : parser.y ;
exe app : app.cpp : <implicit-dependency>parser ;
@@ -652,14 +687,14 @@
targets from "parser" as potential dependencies.
</para>
</section>
-
+
</chapter>
<!--
Local Variables:
mode: xml
- sgml-indent-data: t
+ sgml-indent-data: t
sgml-parent-document: ("userman.xml" "chapter")
sgml-set-face: t
End:
Modified: branches/release/tools/build/v2/doc/src/tutorial.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/tutorial.xml (original)
+++ branches/release/tools/build/v2/doc/src/tutorial.xml 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -16,74 +16,70 @@
sections.
-->
- <para>This section will guide you though the most basic features of
- Boost.Build V2. We will start with the “Hello, world” example,
- learn how to use libraries, and finish with testing and installing features.
+ <para>
+ This section will guide you though the most basic features of Boost.Build
+ V2. We will start with the “Hello, world” example, learn how
+ to use libraries, and finish with testing and installing features.
</para>
<section id="bbv2.tutorial.hello">
<title>Hello, world</title>
- <para>The simplest project that Boost.Build can construct is
- stored in <filename>example/hello/</filename> directory. The
- project is described by a file
- called <filename>Jamroot</filename> that contains:
+ <para>
+ The simplest project that Boost.Build can construct is stored in
+ <filename>example/hello/</filename> directory. The project is described by
+ a file called <filename>Jamroot</filename> that contains:
<programlisting>
exe hello : hello.cpp ;
</programlisting>
- Even with this simple setup, you can do some interesting
- things. First of all, just invoking <command>bjam</command> will
- build the <filename>hello</filename>
- executable by compiling and
- linking <filename>hello.cpp</filename>. By default, debug variant
- is built. Now, to build the
- release variant of <filename>hello</filename>, invoke
+ Even with this simple setup, you can do some interesting things. First of
+ all, just invoking <command>bjam</command> will build the <filename>hello
+ </filename> executable by compiling and linking <filename>hello.cpp
+ </filename>. By default, debug variant is built. Now, to build the release
+ variant of <filename>hello</filename>, invoke
<screen>
bjam release
</screen>
- Note that debug and release variants are created in different
- directories, so you can switch between variants or even build
- multiple variants at once, without any unnecessary
- recompilation. Let's extend the example by adding another line
- to our project's <filename>Jamroot</filename>:
+ Note that debug and release variants are created in different directories,
+ so you can switch between variants or even build multiple variants at
+ once, without any unnecessary recompilation. Let us extend the example by
+ adding another line to our project's <filename>Jamroot</filename>:
<programlisting>
exe hello2 : hello.cpp ;
</programlisting>
- Now let us build both the debug and release variants of our project
- again:
+ Now let us build both the debug and release variants of our project again:
<screen>
bjam debug release
</screen>
- Note that two variants of <filename>hello2</filename> are linked.
- Since we have already built both variants
- of <filename>hello</filename>, hello.cpp won't be recompiled;
- instead the existing object files will just be linked into the
- corresponding variants of <filename>hello2</filename>. Now
- let's remove all the built products:
+ Note that two variants of <filename>hello2</filename> are linked. Since we
+ have already built both variants of <filename>hello</filename>, hello.cpp
+ will not be recompiled; instead the existing object files will just be
+ linked into the corresponding variants of <filename>hello2</filename>. Now
+ let us remove all the built products:
<screen>
bjam --clean debug release
</screen>
- It's also possible to build or clean specific targets. The
- following two commands, respectively, build or clean only the
- debug version of <filename>hello2</filename>.
+ It is also possible to build or clean specific targets. The following two
+ commands, respectively, build or clean only the debug version of
+ <filename>hello2</filename>.
<screen>
bjam hello2
bjam --clean hello2
</screen>
</para>
-
</section>
+
<section id="bbv2.tutorial.properties">
<title>Properties</title>
@@ -97,125 +93,125 @@
value) pair. When a user initiates a build, Boost.Build
automatically translates the requested properties into appropriate
command-line flags for invoking toolset components like compilers
- and linkers.</para>
+ and linkers.
+ </para>
- <para>There are many built-in features that can be combined to
+ <para>
+ There are many built-in features that can be combined to
produce arbitrary build configurations. The following command
builds the project's <code>release</code> variant with inlining
disabled and debug symbols enabled:
-
<screen>
bjam release inlining=off debug-symbols=on
</screen>
-</para>
+ </para>
- <para>Properties on the command-line are specified with the syntax:
+ <para>
+ Properties on the command-line are specified with the syntax:
<screen>
<replaceable>feature-name</replaceable>=<replaceable>feature-value</replaceable>
</screen>
-</para>
+ </para>
- <para>The <option>release</option> and <option>debug</option> that we've seen
- in <command>bjam</command> invocations are just a shorthand way to
- specify values of the <varname>variant</varname> feature. For example, the command
- above could also have been written this way:
+ <para>
+ The <option>release</option> and <option>debug</option> that we have seen
+ in <command>bjam</command> invocations are just a shorthand way to specify
+ values of the <varname>variant</varname> feature. For example, the
+ command above could also have been written this way:
<screen>
bjam variant=release inlining=off debug-symbols=on
</screen>
</para>
- <para> <varname>variant</varname> is so commonly-used that it has
- been given special status as an <firstterm>implicit</firstterm>
- feature—Boost.Build will deduce the its identity just
- from the name of one of its values.
+ <para>
+ <varname>variant</varname> is so commonly-used that it has been given
+ special status as an <firstterm>implicit</firstterm> feature—
+ Boost.Build will deduce the its identity just from the name of one of its
+ values.
</para>
<para>
A complete description of features can be found in <xref linkend="bbv2.reference.features"/>.
</para>
-
<section id="bbv2.tutorial.properties.requirements">
<title>Build Requests and Target Requirements</title>
- <para>
+ <para>
The set of properties specified on the command line constitute
a <firstterm>build request</firstterm>—a description of
the desired properties for building the requested targets (or,
if no targets were explicitly requested, the project in the
- current directory). The <emphasis>actual</emphasis>
+ current directory). The <emphasis>actual</emphasis>
properties used for building targets are typically a
combination of the build request and properties derived from
the project's <filename>Jamroot</filename> (and its other
Jamfiles, as described in <xref
- linkend="bbv2.tutorial.hierarchy"/>). For example, the
+ linkend="bbv2.tutorial.hierarchy"/>). For example, the
locations of <code>#include</code>d header files are normally
not specified on the command-line, but described in
Jamfiles as <firstterm>target
requirements</firstterm> and automatically combined with the
- build request for those targets. Multithread-enabled
+ build request for those targets. Multithread-enabled
compilation is another example of a typical target
- requirement. The Jamfile fragment below
+ requirement. The Jamfile fragment below
illustrates how these requirements might be specified.
</para>
<programlisting>
-exe hello
+exe hello
: hello.cpp
: <include>boost <threading>multi
;
</programlisting>
- <para>
- When <filename>hello</filename> is built, the two
- requirements specified above will always be present.
- If the build request given on the <command>bjam</command>
- command-line explictly contradicts a target's requirements,
- the target requirements usually override (or, in the case of
- “free”” features like
+ <para>
+ When <filename>hello</filename> is built, the two requirements specified
+ above will always be present. If the build request given on the
+ <command>bjam</command> command-line explictly contradicts a target's
+ requirements, the target requirements usually override (or, in the case
+ of “free”” features like
<varname><include></varname>,
<footnote>
-<para>
-See <xref linkend="bbv2.reference.features.attributes"/>
-</para></footnote>
+ <para>
+ See <xref linkend="bbv2.reference.features.attributes"/>
+ </para>
+ </footnote>
augments) the build request.
-
</para>
<tip>
- <para>The value of the <varname><include></varname> feature is
- relative to the location of <filename>Jamroot</filename> where it's
- used.
+ <para>
+ The value of the <varname><include></varname> feature is
+ relative to the location of <filename>Jamroot</filename> where it is
+ used.
</para>
</tip>
-
</section>
+
<section id="bbv2.tutorial.properties.project_attributes">
<title>Project Attributes</title>
<para>
- If we want the same requirements for our other
- target, <filename>hello2</filename>, we could simply duplicate
- them. However, as projects grow, that approach leads to a great
- deal of repeated boilerplate in Jamfiles.
-
- Fortunately, there's a better way. Each project can specify a
- set of <firstterm>attributes</firstterm>, including
- requirements:
+ If we want the same requirements for our other target, <filename>hello2
+ </filename>, we could simply duplicate them. However, as projects grow,
+ that approach leads to a great deal of repeated boilerplate in Jamfiles.
+
+ Fortunately, there's a better way. Each project can specify a set of
+ <firstterm>attributes</firstterm>, including requirements:
<programlisting>
-project
- : requirements <include>/home/ghost/Work/boost <threading>multi
+project
+ : requirements <include>/home/ghost/Work/boost <threading>multi
;
exe hello : hello.cpp ;
-exe hello2 : hello.cpp ;
-</programlisting>
+exe hello2 : hello.cpp ;</programlisting>
- The effect would be as if we specified the same requirement for
- both <filename>hello</filename> and <filename>hello2</filename>.
+ The effect would be as if we specified the same requirement for both
+ <filename>hello</filename> and <filename>hello2</filename>.
</para>
</section>
</section>
@@ -223,20 +219,19 @@
<section id="bbv2.tutorial.hierarchy">
<title>Project Hierarchies</title>
- <para>So far we've only considered examples with one project
- —a. with one user-written Boost.Jam file,
- <filename>Jamroot</filename>). A typical large codebase would be
- composed of many projects organized into a tree. The top of the
- tree is called the <firstterm>project root</firstterm>. Every
- subproject is defined by a file called
- <filename>Jamfile</filename> in a descendant directory of the
- project root. The parent project of a subproject is defined by
- the nearest <filename>Jamfile</filename> or
- <filename>Jamroot</filename> file in an ancestor directory. For
- example, in the following directory layout:
+ <para>
+ So far we have only considered examples with one project —a. with
+ one user-written Boost.Jam file, <filename>Jamroot</filename>). A typical
+ large codebase would be composed of many projects organized into a tree.
+ The top of the tree is called the <firstterm>project root</firstterm>.
+ Every subproject is defined by a file called <filename>Jamfile</filename>
+ in a descendant directory of the project root. The parent project of a
+ subproject is defined by the nearest <filename>Jamfile</filename> or
+ <filename>Jamroot</filename> file in an ancestor directory. For example,
+ in the following directory layout:
<screen>
-top/
+top/
|
+-- Jamroot
|
@@ -244,7 +239,7 @@
| |
| +-- Jamfile
| `-- app.cpp
- |
+ |
`-- util/
|
+-- foo/
@@ -253,10 +248,9 @@
. `-- bar.cpp
</screen>
- the project root is <filename>top/</filename>. The projects in
- <filename>top/app/</filename> and
- <filename>top/util/foo/</filename> are immediate children of the
- root project.
+ the project root is <filename>top/</filename>. The projects in
+ <filename>top/app/</filename> and <filename>top/util/foo/</filename> are
+ immediate children of the root project.
<note>
<para>
@@ -274,7 +268,7 @@
<para>
Projects inherit all attributes (such as requirements)
from their parents. Inherited requirements are combined with
- any requirements specified by the subproject.
+ any requirements specified by the subproject.
For example, if <filename>top/Jamroot</filename> has
<programlisting>
@@ -289,8 +283,8 @@
rather than added-to, in subprojects. See <xref
linkend="bbv2.reference.features.attributes"/> for more
information</para>
- </footnote>
- More details can be found in
+ </footnote>
+ More details can be found in
<xref linkend= "bbv2.advanced.projects"/>.
</para>
@@ -346,7 +340,7 @@
While <code>app.cpp</code> refers to a regular source file,
<code>../util/foo//bar</code> is a reference to another target:
a library <filename>bar</filename> declared in the Jamfile at
- <filename>../util/foo</filename>.
+ <filename>../util/foo</filename>.
</para>
<tip>
@@ -372,241 +366,223 @@
</para>
- <para>Let's improve this project further.
- The library
- probably has some headers that must be used when compiling
- <filename>app.cpp</filename>. We could manually add the necessary
- <code>#include</code> paths to <filename>app</filename>'s
- requirements as values of the
- <varname><include></varname> feature, but then this work will
- be repeated for all programs
+ <para>
+ Let's improve this project further. The library probably has some headers
+ that must be used when compiling <filename>app.cpp</filename>. We could
+ manually add the necessary <code>#include</code> paths to <filename>app
+ </filename>'s requirements as values of the <varname><include>
+ </varname> feature, but then this work will be repeated for all programs
that use <filename>foo</filename>. A better solution is to modify
<filename>util/foo/Jamfile</filename> in this way:
-<programlisting>
-project
+ <programlisting>
+project
: usage-requirements <include>.
;
-lib foo : foo.cpp ;
-</programlisting>
+lib foo : foo.cpp ;</programlisting>
- Usage requirements are applied not to the target being declared
- but to its
- dependents. In this case, <literal><include>.</literal> will be applied to all
- targets that directly depend on <filename>foo</filename>.
- </para>
-
- <para>Another improvement is using symbolic identifiers to refer to
- the library, as opposed to <filename>Jamfile</filename> location.
- In a large project, a library can be used by many targets, and if
- they all use <filename>Jamfile</filename> location,
- a change in directory organization entails much work.
- The solution is to use project ids—symbolic names
- not tied to directory layout. First, we need to assign a project id by
- adding this code to
- <filename>Jamroot</filename>:</para>
- <programlisting>
-use-project /library-example/foo : util/foo ;
- </programlisting>
- <para>Second, we modify <filename>app/Jamfile</filename> to use the
- project id:
+ Usage requirements are applied not to the target being declared but to its
+ dependants. In this case, <literal><include>.</literal> will be
+ applied to all targets that directly depend on <filename>foo</filename>.
+ </para>
-<programlisting>
-exe app : app.cpp /library-example/foo//bar ;
-</programlisting>
-The <filename>/library-example/foo//bar</filename> syntax is used
- to refer to the target <filename>bar</filename> in
- the project with id <filename>/library-example/foo</filename>.
- We've achieved our goal—if the library is moved to a different
- directory, only <filename>Jamroot</filename> must be modified.
- Note that project ids are global—two Jamfiles are not
- allowed to assign the same project id to different directories.
-
+ <para>
+ Another improvement is using symbolic identifiers to refer to the library,
+ as opposed to <filename>Jamfile</filename> location. In a large project, a
+ library can be used by many targets, and if they all use <filename>Jamfile
+ </filename> location, a change in directory organization entails much
+ work. The solution is to use project ids—symbolic names not tied to
+ directory layout. First, we need to assign a project id by adding this
+ code to <filename>Jamroot</filename>:
+ </para>
+
+ <programlisting>
+use-project /library-example/foo : util/foo ;</programlisting>
+
+ <para>
+ Second, we modify <filename>app/Jamfile</filename> to use the project id:
+ <programlisting>
+exe app : app.cpp /library-example/foo//bar ;</programlisting>
+
+ The <filename>/library-example/foo//bar</filename> syntax is used to refer
+ to the target <filename>bar</filename> in the project with id <filename>
+ /library-example/foo</filename>. We've achieved our goal—if the
+ library is moved to a different directory, only <filename>Jamroot
+ </filename> must be modified. Note that project ids are global—two
+ Jamfiles are not allowed to assign the same project id to different
+ directories.
</para>
<tip>
- <para>If you want all applications in some project to link
- to a certain library, you can avoid having to specify it directly the sources of every
- target by using the
- <varname><library></varname> property. For example, if <filename>/boost/filesystem//fs</filename>
- should be linked to all applications in your project, you can add
- <code><library>/boost/filesystem//fs</code> to the project's requirements, like this:</para>
+ <para>If you want all applications in some project to link to a certain
+ library, you can avoid having to specify it directly the sources of
+ every target by using the <varname><library></varname> property.
+ For example, if <filename>/boost/filesystem//fs</filename> should be
+ linked to all applications in your project, you can add
+ <code><library>/boost/filesystem//fs</code> to the project's
+ requirements, like this:
+ </para>
<programlisting>
-project
+project
: requirements <source>/boost/filesystem//fs
- ;
- </programlisting>
+ ;</programlisting>
</tip>
-
</section>
<section id="bbv2.tutorial.testing">
<title>Testing</title>
-
-
</section>
<section id="bbv2.tutorial.linkage">
<title>Static and shared libaries</title>
- <para>Libraries can be either
- <emphasis>static</emphasis>, which means they are included in executable
- files that use them, or <emphasis>shared</emphasis> (a.k.a.
- <emphasis>dynamic</emphasis>), which are only referred to from executables,
- and must be available at run time. Boost.Build can create and use both kinds.
- </para>
-
- <para>The kind of library produced from a <code>lib</code> target is
- determined by the value of the <varname>link</varname> feature. Default
- value is <literal>shared</literal>, and to build static library, the value
- should be <literal>static</literal>. You can either requiest static build
- on the command line:
- <screen>
-bjam link=static
- </screen>
- or in the library's requirements:
- <programlisting>
-lib l : l.cpp : <link>static ;
- </programlisting>
+ <para>
+ Libraries can be either <emphasis>static</emphasis>, which means they are
+ included in executable files that use them, or <emphasis>shared</emphasis>
+ (a.k.a. <emphasis>dynamic</emphasis>), which are only referred to from
+ executables, and must be available at run time. Boost.Build can create and
+ use both kinds.
</para>
<para>
- We can also use the <varname><link></varname> property
- to express linking requirements on a per-target basis.
- For example, if a particular executable can be correctly built
- only with the static version of a library, we can qualify the
- executable's <link
- linkend="bbv2.reference.targets.references">target
- reference</link> to the library as follows:
-
-<!-- There has been no earlier indication that target references can
- contain properties. You can't assume that the reader will
- recognize that strange incantation as a target reference, or that
- she'll know what it means. You also can't assume that hyperlinks
- will help the reader, because she may be working from a printout,
- as I was.
- VP: to be addressed when this section is moved. See comment
- below.
+ The kind of library produced from a <code>lib</code> target is determined
+ by the value of the <varname>link</varname> feature. Default value is
+ <literal>shared</literal>, and to build a static library, the value should
+ be <literal>static</literal>. You can request a static build either on the
+ command line:
+ <programlisting>bjam link=static</programlisting>
+ or in the library's requirements:
+ <programlisting>lib l : l.cpp : <link>static ;</programlisting>
+ </para>
+
+ <para>
+ We can also use the <varname><link></varname> property to express
+ linking requirements on a per-target basis. For example, if a particular
+ executable can be correctly built only with the static version of a
+ library, we can qualify the executable's <link
+ linkend="bbv2.reference.targets.references">target reference</link> to the
+ library as follows:
+
+<!-- There has been no earlier indication that target references can contain
+ properties. You can't assume that the reader will recognize that strange
+ incantation as a target reference, or that she'll know what it means. You
+ also can't assume that hyperlinks will help the reader, because she may be
+ working from a printout, as I was.
+ VP: to be addressed when this section is moved. See comment below.
-->
- <programlisting>
+ <programlisting>
exe important : main.cpp helpers/<link>static ;</programlisting>
- No matter what arguments are specified on the <command>bjam</command>
- command line, <filename>important</filename> will only be linked with
- the static version of <filename>helpers</filename>.
+ No matter what arguments are specified on the <command>bjam</command>
+ command line, <filename>important</filename> will only be linked with the
+ static version of <filename>helpers</filename>.
</para>
- <para>
- Specifying properties in target references is especially useful if you
- use a library defined in some other project (one you can't
- change) but you still want static (or dynamic) linking to that library
- in all cases. If that library is used by many targets,
- you <emphasis>could</emphasis> use target references
- everywhere:
+ <para>
+ Specifying properties in target references is especially useful if you use
+ a library defined in some other project (one you can't change) but you
+ still want static (or dynamic) linking to that library in all cases. If
+ that library is used by many targets, you <emphasis>could</emphasis> use
+ target references everywhere:
- <programlisting>
+ <programlisting>
exe e1 : e1.cpp /other_project//bar/<link>static ;
exe e10 : e10.cpp /other_project//bar/<link>static ;</programlisting>
- but that's far from being convenient. A better approach is
- to introduce a level of indirection. Create a local
- <type>alias</type> target that refers to the static (or
- dynamic) version of <filename>foo</filename>:
+ but that's far from being convenient. A better approach is to introduce a
+ level of indirection. Create a local <type>alias</type> target that refers
+ to the static (or dynamic) version of <filename>foo</filename>:
- <programlisting>
+ <programlisting>
alias foo : /other_project//bar/<link>static ;
exe e1 : e1.cpp foo ;
exe e10 : e10.cpp foo ;</programlisting>
- The <link linkend="bbv2.tasks.alias"><functionname>alias</functionname></link>
- rule is specifically used to rename a reference to a target and possibly
- change the properties.
-
- <!-- You should introduce the alias rule in an earlier
- section, before describing how it applies to this
- specific use-case, and the foregoing sentence should
- go there.
- VP: we've agreed that this section should be moved further
- in the docs, since it's more like advanced reading. When
- I'll move it, I'll make sure 'alias' is already mentioned.
- -->
- </para>
+ The <link linkend="bbv2.tasks.alias"><functionname>alias</functionname>
+ </link> rule is specifically used to rename a reference to a target and
+ possibly change the properties.
+
+ <!-- You should introduce the alias rule in an earlier section, before
+ describing how it applies to this specific use-case, and the
+ foregoing sentence should go there.
+ VP: we've agreed that this section should be moved further in the
+ docs, since it's more like advanced reading. When I move it, I'll
+ make sure 'alias' is already mentioned.
+ -->
+ </para>
- <tip>
- <para>
- When one library uses another, you put the second library in
- the source list of the first. For example:
- <programlisting>
-lib utils : utils.cpp /boost/filesystem//fs ;
+ <tip>
+ <para>
+ When one library uses another, you put the second library in the source
+ list of the first. For example:
+ <programlisting>
+lib utils : utils.cpp /boost/filesystem//fs ;
lib core : core.cpp utils ;
exe app : app.cpp core ;</programlisting>
- This works no matter what kind of linking is used. When
- <filename>core</filename> is built as a shared library, it is linked
- directly into <filename>utils</filename>. Static libraries can't
- link to other libraries, so when <filename>core</filename> is built
- as a static library, its dependency on <filename>utils</filename> is passed along to
- <filename>core</filename>'s dependents, causing
- <filename>app</filename> to be linked with both
- <filename>core</filename> and <filename>utils</filename>.
- </para>
- </tip>
+ This works no matter what kind of linking is used. When <filename>core
+ </filename> is built as a shared library, it is linked directly into
+ <filename>utils</filename>. Static libraries can't link to other
+ libraries, so when <filename>core</filename> is built as a static
+ library, its dependency on <filename>utils</filename> is passed along to
+ <filename>core</filename>'s dependents, causing <filename>app</filename>
+ to be linked with both <filename>core</filename> and <filename>utils
+ </filename>.
+ </para>
+ </tip>
- <note>
- <para>(Note for non-UNIX system). Typically, shared libraries must be
- installed to a directory in the dynamic linker's search
- path. Otherwise, applications that use shared libraries can't be
- started. On Windows, the dynamic linker's search path is given by the
- <envar>PATH</envar> environment variable. This restriction is lifted
- when you use Boost.Build testing facilities—the
- <envar>PATH</envar> variable will be automatically adjusted before
- running executable.
+ <note>
+ <para>
+ (Note for non-UNIX system). Typically, shared libraries must be
+ installed to a directory in the dynamic linker's search path. Otherwise,
+ applications that use shared libraries can't be started. On Windows, the
+ dynamic linker's search path is given by the <envar>PATH</envar>
+ environment variable. This restriction is lifted when you use
+ Boost.Build testing facilities—the <envar>PATH</envar> variable
+ will be automatically adjusted before running the executable.
<!-- Need ref here to 'testing facilities' -->
- </para>
- </note>
-
+ </para>
+ </note>
</section>
<section id="bbv2.tutorial.conditions">
<title>Conditions and alternatives</title>
- <para>Sometimes, particular relationships need to be maintained
- among a target's build properties. For example, you might want to set
- specific <code>#define</code> when a library is built as shared,
- or when a target's <code>release</code> variant is built.
- This can be achieved with <firstterm>conditional requirements</firstterm>.
+ <para>
+ Sometimes, particular relationships need to be maintained among a target's
+ build properties. For example, you might want to set specific <code>
+ #define</code> when a library is built as shared, or when a target's
+ <code>release</code> variant is built. This can be achieved using
+ <firstterm>conditional requirements</firstterm>.
- <programlisting>
-lib network : network.cpp
+ <programlisting>
+lib network : network.cpp
: <emphasis role="bold"><link>shared:<define>NEWORK_LIB_SHARED</emphasis>
<variant>release:<define>EXTRA_FAST
- ;
-</programlisting>
+ ;</programlisting>
- In the example above, whenever <filename>network</filename> is
- built with <code><link>shared</code>,
- <code><define>NEWORK_LIB_SHARED</code> will be in its
- properties, too. Also, whenever its release variant is built,
- <code><define>EXTRA_FAST</code> will appear in its properties.
+ In the example above, whenever <filename>network</filename> is built with
+ <code><link>shared</code>, <code><define>NEWORK_LIB_SHARED
+ </code> will be in its properties, too. Also, whenever its release variant
+ is built, <code><define>EXTRA_FAST</code> will appear in its
+ properties.
</para>
<para>
- Sometimes the ways a target is built are so different that
- describing them using conditional requirements would be
- hard. For example, imagine that a library actually uses
- different source files depending on the toolset used to build
- it. We can express this situation using <firstterm>target
+ Sometimes the ways a target is built are so different that describing them
+ using conditional requirements would be hard. For example, imagine that a
+ library actually uses different source files depending on the toolset used
+ to build it. We can express this situation using <firstterm>target
alternatives</firstterm>:
-<programlisting>
+ <programlisting>
lib demangler : dummy_demangler.cpp ; # alternative 1
lib demangler : demangler_gcc.cpp : <toolset>gcc ; # alternative 2
-lib demangler : demangler_msvc.cpp : <toolset>msvc ; # alternative 3
-</programlisting>
+lib demangler : demangler_msvc.cpp : <toolset>msvc ; # alternative 3</programlisting>
When building <filename>demangler</filename>, Boost.Build will compare
requirements for each alternative with build properties to find the best
- match. For example, when building with <code><toolset>gcc</code>
+ match. For example, when building with <code><toolset>gcc</code>
alternative 2, will be selected, and when building with
<code><toolset>msvc</code> alternative 3 will be selected. In all
other cases, the most generic alternative 1 will be built.
@@ -622,77 +598,71 @@
<varname>file</varname> property. Target alternatives can be used to
associate multiple library files with a single conceptual target. For
example:
-<programlisting>
+ <programlisting>
# util/lib2/Jamfile
lib lib2
- :
+ :
: <file>lib2_release.a <variant>release
;
lib lib2
- :
+ :
: <file>lib2_debug.a <variant>debug
- ;
-</programlisting>
+ ;</programlisting>
This example defines two alternatives for <filename>lib2</filename>, and
for each one names a prebuilt file. Naturally, there are no sources.
Instead, the <varname><file></varname> feature is used to specify
the file name.
</para>
- <para>
- Once a prebuilt target has been declared, it can be used just like any other target:
-<programlisting>
-exe app : app.cpp ../util/lib2//lib2 ;
-</programlisting>
+ <para>
+ Once a prebuilt target has been declared, it can be used just like any
+ other target:
- As with any target, the alternative selected depends on the
- properties propagated from <filename>lib2</filename>'s dependents.
- If we build the the release and debug versions of <filename>app</filename> will be linked
- with <filename>lib2_release.a</filename> and <filename>lib2_debug.a</filename>, respectively.
+ <programlisting>
+exe app : app.cpp ../util/lib2//lib2 ;</programlisting>
+ As with any target, the alternative selected depends on the properties
+ propagated from <filename>lib2</filename>'s dependants. If we build the
+ release and debug versions of <filename>app</filename> will be linked
+ with <filename>lib2_release.a</filename> and <filename>lib2_debug.a
+ </filename>, respectively.
</para>
<para>
- System libraries—those that are automatically found by
- the toolset by searching through some set of predetermined
- paths—should be declared almost like regular ones:
+ System libraries—those that are automatically found by the toolset
+ by searching through some set of predetermined paths—should be
+ declared almost like regular ones:
-<programlisting>
-lib pythonlib : : <name>python22 ;
-</programlisting>
+ <programlisting>
+lib pythonlib : : <name>python22 ;</programlisting>
- We again don't specify any sources, but give a
- <varname>name</varname> that should be passed to the
- compiler. If the gcc toolset were used to link an executable
- target to <filename>pythonlib</filename>, <option>-lpython22</option>
- would appear in the command line (other compilers may use
- different options).
+ We again don't specify any sources, but give a <varname>name</varname>
+ that should be passed to the compiler. If the gcc toolset were used to
+ link an executable target to <filename>pythonlib</filename>,
+ <option>-lpython22</option> would appear in the command line (other
+ compilers may use different options).
</para>
<para>
We can also specify where the toolset should look for the library:
-<programlisting>
-lib pythonlib : : <name>python22 <search>/opt/lib ;
-</programlisting>
+ <programlisting>
+lib pythonlib : : <name>python22 <search>/opt/lib ;</programlisting>
And, of course, target alternatives can be used in the usual way:
-<programlisting>
+ <programlisting>
lib pythonlib : : <name>python22 <variant>release ;
-lib pythonlib : : <name>python22_d <variant>debug ;
-</programlisting>
-
+lib pythonlib : : <name>python22_d <variant>debug ;</programlisting>
</para>
- <para>A more advanced use of prebuilt targets is described in <xref
- linkend="bbv2.recipies.site-config"/>.
+ <para>
+ A more advanced use of prebuilt targets is described in <xref linkend=
+ "bbv2.recipies.site-config"/>.
</para>
-
</section>
-
</chapter>
<!--
Modified: branches/release/tools/build/v2/index.html
==============================================================================
--- branches/release/tools/build/v2/index.html (original)
+++ branches/release/tools/build/v2/index.html 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -112,7 +112,7 @@
<li><b>Standalone</b>. Boost.Build's only dependency is a C compiler,
so it's easy to setup. You can even include all of Boost.Build in your
- project. Boost.Build does not use depend on C++ Boost in any way.</li>
+ project. Boost.Build does not depend on C++ Boost in any way.</li>
</ul>
<h2>Status and future</h2>
Modified: branches/release/tools/build/v2/kernel/bootstrap.jam
==============================================================================
--- branches/release/tools/build/v2/kernel/bootstrap.jam (original)
+++ branches/release/tools/build/v2/kernel/bootstrap.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -94,12 +94,8 @@
util # low-level substrate: string/number handling, etc.
build # essential elements of the build system architecture
tools # toolsets for handling specific build jobs and targets.
-
- new # until we get everything sorted out, there is
- # still some code here
-
+ contrib # user contributed (unreviewed) modules
. # build-system.jam lives here
-
;
local whereami = [ NORMALIZE_PATH $(.bootstrap-file:DT) ] ;
BOOST_BUILD_PATH += $(whereami:D)/$(subdirs) ;
Modified: branches/release/tools/build/v2/kernel/class.jam
==============================================================================
--- branches/release/tools/build/v2/kernel/class.jam (original)
+++ branches/release/tools/build/v2/kernel/class.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,16 +1,16 @@
-# Copyright 2001, 2002, 2003 Dave Abrahams
-# Copyright 2002, 2005 Rene Rivera
-# Copyright 2002, 2003 Vladimir Prus
-# 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)
+# Copyright 2001, 2002, 2003 Dave Abrahams
+# Copyright 2002, 2005 Rene Rivera
+# Copyright 2002, 2003 Vladimir Prus
+# 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)
# Polymorphic class system built on top of core Jam facilities.
#
# Classes are defined by 'class' keywords::
#
-# class myclass ( arg1 )
+# class myclass
# {
-# rule __init__ ( ) # constructor
+# rule __init__ ( arg1 ) # constructor
# {
# self.attribute = $(arg1) ;
# }
@@ -28,14 +28,14 @@
#
# The __init__ rule is the constructor, and sets member variables.
#
-# New instances are created by invoking [ new <class> <args...> ]::
+# New instances are created by invoking [ new <class> <args...> ]:
#
# local x = [ new myclass foo ] ; # x is a new myclass object
# assert.result foo : [ $(x).method1 ] ; # $(x).method1 returns "foo"
#
# Derived class are created by mentioning base classes in the declaration::
#
-# class derived : myclass
+# class derived : myclass
# {
# rule __init__ ( arg )
# {
@@ -49,26 +49,21 @@
# }
# }
#
-# All methods operate virtually, replacing behavior in the base
-# classes. For example::
+# All methods operate virtually, replacing behavior in the base classes. For
+# example::
#
-# local y = [ new derived foo ] ; # y is a new derived object
-# assert.result fooXXX : [ $(y).method1 ] ; # $(y).method1 returns "foo"
+# local y = [ new derived foo ] ; # y is a new derived object
+# assert.result fooXXX : [ $(y).method1 ] ; # $(y).method1 returns "foo"
#
-# Each class instance is its own core Jam module. All instance
-# attributes and methods are accessible without additional
-# qualification from within the class instance. All rules imported in
-# class declaration, or visible in base classses are also visible.
-# Base methods are available in qualified form: base-name.method-name.
-# By convention, attribute names are prefixed with "self.".
+# Each class instance is its own core Jam module. All instance attributes and
+# methods are accessible without additional qualification from within the class
+# instance. All rules imported in class declaration, or visible in base classses
+# are also visible. Base methods are available in qualified form:
+# base-name.method-name. By convention, attribute names are prefixed with
+# "self.".
-import numbers ;
-import errors : * ;
-import set ;
import modules ;
-import assert ;
-
-classes = ;
+import numbers ;
rule xinit ( instance : class )
@@ -77,7 +72,7 @@
{
__class__ = $(2) ;
__name__ = $(1) ;
- }
+ }
}
@@ -85,16 +80,16 @@
{
.next-instance ?= 1 ;
local id = object($(class))@$(.next-instance) ;
-
+
xinit $(id) : $(class) ;
-
+
INSTANCE $(id) : class@$(class) ;
- IMPORT_MODULE $(id) : ;
+ IMPORT_MODULE $(id) ;
$(id).__init__ $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
-
- # bump the next unique object name
+
+ # Bump the next unique object name.
.next-instance = [ numbers.increment $(.next-instance) ] ;
-
+
# Return the name of the new instance.
return $(id) ;
}
@@ -102,28 +97,18 @@
rule bases ( class )
{
- #if ! ( $(class) in $(classes) )
- #{
- # error class $(class) not defined ;
- #}
-
module class@$(class)
{
return $(__bases__) ;
}
}
+
rule is-derived ( class : bases + )
{
- #local all = $(class) $(bases) ;
- #if ! ( $(all) in $(classes) )
- #{
- # error class(es) [ set.difference $(class) $(bases) : $(classes) ] not defined ;
- #}
-
local stack = $(class) ;
local visited found ;
- while ( ! $(found) ) && $(stack)
+ while ! $(found) && $(stack)
{
local top = $(stack[1]) ;
stack = $(stack[2-]) ;
@@ -131,7 +116,7 @@
{
visited += $(top) ;
stack += [ bases $(top) ] ;
-
+
if $(bases) in $(visited)
{
found = true ;
@@ -141,19 +126,21 @@
return $(found) ;
}
+
# Returns true if the 'value' is a class instance.
-rule is-instance ( value # The value to check
- )
+#
+rule is-instance ( value )
{
- return [ MATCH "^(object\\()[^@]+\\)@.*" : $(value) ] ;
+ return [ MATCH "^(object\\()[^@]+\\)@.*" : $(value) ] ;
}
+
# Check if the given value is of the given type.
#
rule is-a (
- instance # The value to check.
- : type # The type to test for.
- )
+ instance # The value to check.
+ : type # The type to test for.
+)
{
if [ is-instance $(instance) ]
{
@@ -161,6 +148,7 @@
}
}
+
local rule typecheck ( x )
{
local class-name = [ MATCH "^\\[(.*)\\]$" : [ BACKTRACE 1 ] ] ;
@@ -170,26 +158,26 @@
}
}
-local rule __test__ ( )
+
+rule __test__ ( )
{
- import "class" : * ;
import assert ;
- import errors : * ;
+ import "class" : new ;
- # This will be the construction function for a class called
- # 'myclass'
- class myclass
+ # This will be the construction function for a class called 'myclass'.
+ #
+ class myclass
{
- import assert : nonempty-variable ;
-
+ import assert ;
+
rule __init__ ( x_ * : y_ * )
- {
- # set some instance variables
+ {
+ # Set some instance variables.
x = $(x_) ;
y = $(y_) ;
foo += 10 ;
}
-
+
rule set-x ( newx * )
{
x = $(newx) ;
@@ -235,33 +223,34 @@
{
return $(__class__) ;
}
-
+
rule get-instance ( )
{
return $(__name__) ;
}
-
+
rule invariant ( )
{
assert.equal 1 : 1 ;
- }
-
+ }
+
rule get-foo ( )
{
return $(foo) ;
- }
+ }
}
# class myclass ;
class derived1 : myclass
- {
+ {
rule __init__ ( z_ )
{
myclass.__init__ $(z_) : X ;
- z = $(z_) ;
+ z = $(z_) ;
}
-
- # override g
+
+ # Override g.
+ #
rule g ( args * )
{
return derived1.g ;
@@ -277,50 +266,53 @@
return $(z) ;
}
- # Check that 'assert.equal' visible in base class is visible
- # here.
+ # Check that 'assert.equal' visible in base class is visible here.
+ #
rule invariant2 ( )
{
assert.equal 2 : 2 ;
- }
-
- # Check that 'nonempty-variable' visible in base class is
+ }
+
+ # Check that 'assert.variable-not-empty' visible in base class is
# visible here.
+ #
rule invariant3 ( )
{
local v = 10 ;
- nonempty-variable v ;
- }
+ assert.variable-not-empty v ;
+ }
}
# class derived1 : myclass ;
- class derived2 : myclass
+ class derived2 : myclass
{
rule __init__ ( )
- {
+ {
myclass.__init__ 1 : 2 ;
}
-
- # override g
+
+ # Override g.
+ #
rule g ( args * )
{
return derived2.g ;
}
- rule get-x ( )
- {
- # Test the ability to call base class functions with qualification.
- return [ myclass.get-x ] ;
- }
+ # Test the ability to call base class functions with qualification.
+ #
+ rule get-x ( )
+ {
+ return [ myclass.get-x ] ;
+ }
}
# class derived2 : myclass ;
class derived2a : derived2
{
- rule __init__
+ rule __init__
{
derived2.__init__ ;
- }
+ }
}
# class derived2a : derived2 ;
@@ -336,11 +328,10 @@
expect_derived2 $(d) ;
expect_derived2 $(e) ;
- # argument checking is set up to call exit(1) directly on
- # failure, and we can't hijack that with try, so we'd better
- # not do this test by default. We could fix this by having
- # errors look up and invoke the EXIT rule instead; EXIT can be
- # hijacked (;-)
+ # Argument checking is set up to call exit(1) directly on failure, and we
+ # can not hijack that with try, so we should better not do this test by
+ # default. We could fix this by having errors look up and invoke the EXIT
+ # rule instead; EXIT can be hijacked (;-)
if --fail-typecheck in [ modules.peek : ARGV ]
{
try ;
@@ -348,11 +339,10 @@
expect_derived2 $(a) ;
}
catch
- "Expected an instance of derived2 but got" instead
- ;
+ "Expected an instance of derived2 but got" instead
+ ;
}
-
#try ;
#{
# new bad_subclass ;
@@ -378,14 +368,14 @@
assert.result derived1.g : $(b).f ;
assert.result derived2.g : $(c).f ;
assert.result derived2.g : $(d).f ;
-
+
assert.result 10 : $(b).get-foo ;
-
+
$(a).invariant ;
$(b).invariant2 ;
$(b).invariant3 ;
-
- # Check that the __class__ attribute is getting properly set.
+
+ # Check that the __class__ attribute is getting properly set.
assert.result myclass : $(a).get-class ;
assert.result derived1 : $(b).get-class ;
assert.result $(a) : $(a).get-instance ;
@@ -399,13 +389,12 @@
assert.result c.x : $(c).get-x ;
assert.result d.x : $(d).get-x ;
- class derived3 : derived1 derived2
+ class derived3 : derived1 derived2
{
rule __init__ ( )
{
}
}
-
assert.result : bases myclass ;
assert.result myclass : bases derived1 ;
Modified: branches/release/tools/build/v2/kernel/errors.jam
==============================================================================
--- branches/release/tools/build/v2/kernel/errors.jam (original)
+++ branches/release/tools/build/v2/kernel/errors.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -6,6 +6,7 @@
# Print a stack backtrace leading to this rule's caller. Each argument
# represents a line of output to be printed after the first line of the
# backtrace.
+#
rule backtrace ( skip-frames prefix messages * : * )
{
local frame-skips = 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 ;
@@ -71,6 +72,7 @@
# message matched expectations.
# Begin looking for error messages.
+#
rule try ( )
{
.disabled += true ;
@@ -80,13 +82,14 @@
# Stop looking for error messages; generate an error if an argument of messages
# is not found in the corresponding argument in the error call.
+#
rule catch ( messages * : * )
{
.disabled = $(.disabled[2-]) ; # Pop the stack.
import sequence ;
- if ! $(.last-error-$(.args))-is-nonempty
+ if ! $(.last-error-$(.args))-is-not-empty
{
error-skip-frames 3 expected an error, but none occurred ;
}
@@ -102,7 +105,7 @@
.last-error-$(.args) = ;
error-skip-frames 3 expected \"$(v)\" in argument $(n) of error
- : got \"$(joined)\" instead ;
+ : got \"$(joined)\" instead ;
}
}
}
@@ -134,6 +137,7 @@
# Print an error message with a stack backtrace and exit.
+#
rule error ( messages * : * )
{
if $(.no-error-backtrace)
@@ -164,6 +168,7 @@
# Same as 'error', but the generated backtrace will include only user files.
+#
rule user-error ( messages * : * )
{
.user-modules-only = 1 ;
@@ -172,6 +177,7 @@
# Print a warning message with a stack backtrace and exit.
+#
rule warning
{
backtrace 2 warning: $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
@@ -182,6 +188,7 @@
# elements representing the same information. This is mostly useful for
# formatting descriptions of arguments with which a rule was called when
# reporting an error.
+#
rule lol->list ( * )
{
local result ;
@@ -203,6 +210,7 @@
# Return the file:line for the nearest entry in backtrace which correspond to a
# user module.
+#
rule nearest-user-location ( )
{
local bt = [ BACKTRACE ] ;
Modified: branches/release/tools/build/v2/kernel/modules.jam
==============================================================================
--- branches/release/tools/build/v2/kernel/modules.jam (original)
+++ branches/release/tools/build/v2/kernel/modules.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -10,26 +10,55 @@
# dependencies.
.loading ?= ;
-# A list of modules needing to be tested via __test__ rule.
+# A list of modules needing to be tested using their __test__ rule.
.untested ?= ;
-# A list of modules which have been tested via __test__.
+# A list of modules which have been tested using their __test__ rule.
.tested ?= ;
-# Meant to be invoked from import when no __test__ rule is defined in the given
-# module.
-local rule no-test-defined
+# Runs internal Boost Build unit tests for the specified module. The module's
+# __test__ rule is executed in its own module to eliminate any inadvertent
+# effects of testing module dependencies (such as assert) on the module itself.
+#
+local rule run-module-test ( m )
{
- import modules ;
- if ! ( --quiet in [ modules.peek : ARGV ] )
+ local tested-modules = [ modules.peek modules : .tested ] ;
+
+ if ( ! $(m) in $(tested-modules) ) # Avoid recursive test invocations.
+ && ( ( --debug in $(argv) ) || ( --debug-module=$(m) in $(argv) ) )
{
- ECHO warning: no __test__ rule defined in module $(__module__) ;
+ modules.poke modules : .tested : $(tested-modules) $(m) ;
+
+ if ! ( __test__ in [ RULENAMES $(m) ] )
+ {
+ local argv = [ peek : ARGV ] ;
+ if ! ( --quiet in $(argv) ) && ( --debug-tests in $(argv) )
+ {
+ ECHO warning: no __test__ rule defined in module $(m) ;
+ }
+ }
+ else
+ {
+ if ! ( --quiet in $(argv) )
+ {
+ ECHO testing module $(m)... ;
+ }
+
+ local test-module = __test-$(m)__ ;
+ IMPORT $(m) : [ RULENAMES $(m) ] : $(test-module) : [ RULENAMES $(m) ] ;
+ IMPORT $(m) : __test__ : $(test-module) : __test__ : LOCALIZE ;
+ module $(test-module)
+ {
+ __test__ ;
+ }
+ }
}
}
# Return the binding of the given module.
+#
rule binding ( module )
{
return $($(module).__binding__) ;
@@ -39,6 +68,7 @@
# Sets the module-local value of a variable. This is the most reliable way to
# set a module-local variable in a different module; it eliminates issues of
# name shadowing due to dynamic scoping.
+#
rule poke ( module-name ? : variables + : value * )
{
module $(<)
@@ -51,6 +81,7 @@
# Returns the module-local value of a variable. This is the most reliable way to
# examine a module-local variable in a different module; it eliminates issues of
# name shadowing due to dynamic scoping.
+#
rule peek ( module-name ? : variables + )
{
module $(<)
@@ -63,7 +94,8 @@
# Call the given rule locally in the given module. Use this for rules accepting
# rule names as arguments, so that the passed rule may be invoked in the context
# of the rule's caller (for example, if the rule accesses module globals or is a
-# local rule).
+# local rule). Note that rules called this way may accept at most 8 parameters.
+#
rule call-in ( module-name ? : rule-name args * : * )
{
module $(module-name)
@@ -75,18 +107,24 @@
# Given a possibly qualified rule name and arguments, remove any initial module
# qualification from the rule and invoke it in that module. If there is no
-# module qualification, the rule is invoked in the global module.
+# module qualification, the rule is invoked in the global module. Note that
+# rules called this way may accept at most 8 parameters.
+#
rule call-locally ( qualified-rule-name args * : * )
{
local module-rule = [ MATCH (.*)\\.(.*) : $(qualified-rule-name) ] ;
local rule-name = $(module-rule[2]) ;
rule-name ?= $(qualified-rule-name) ;
- return [ call-in $(module-rule[1]) : $(rule-name) $(args)
- : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+ # We pass only 8 parameters here since Boost Jam allows at most 9 rule
+ # parameter positions and the call-in rule already uses up the initial
+ # position for the module name.
+ return [ call-in $(module-rule[1]) : $(rule-name) $(args) : $(2) : $(3) :
+ $(4) : $(5) : $(6) : $(7) : $(8) ] ;
}
# Load the indicated module if it is not already loaded.
+#
rule load (
module-name # Name of module to load. Rules will be defined in this
# module.
@@ -95,12 +133,12 @@
# $(BOOST_BUILD_PATH).
)
{
- # Avoid loading modules twice
+ # Avoid loading modules twice.
if ! ( $(module-name) in $(.loaded) )
{
filename ?= $(module-name).jam ;
- # Mark the module loaded so we don't try to load it recursively.
+ # Mark the module loaded so we do not try to load it recursively.
.loaded += $(module-name) ;
# Suppress tests if any module loads are already in progress.
@@ -109,7 +147,7 @@
# Push this module on the loading stack.
.loading += $(module-name) ;
- # Remember that it's untested.
+ # Remember that it is untested.
.untested += $(module-name) ;
# Insert the new module's __name__ and __file__ globals.
@@ -118,9 +156,6 @@
module $(module-name)
{
- # Prepare default behavior, in case no __test__ is defined.
- IMPORT modules : no-test-defined : $(__name__) : __test__ ;
-
# Add some grist so that the module will have a unique target name.
local module-target = $(__file__:G=module@) ;
@@ -139,11 +174,11 @@
if $(module-name) != modules && ! [ binding $(module-name) ]
{
import errors ;
- errors.error "Couldn't find module" $(module-name) in $(search) ;
+ errors.error "Could not find module" $(module-name) in $(search) ;
}
- # Pop the loading stack. Must happen before testing or we'll run into a
- # circular loading dependency.
+ # Pop the loading stack. Must happen before testing or we will run into
+ # a circular loading dependency.
.loading = $(.loading[1--2]) ;
# Run any pending tests if this is an outer load.
@@ -152,31 +187,7 @@
local argv = [ peek : ARGV ] ;
for local m in $(.untested)
{
- if ( ! $(m) in $(.tested) ) # Avoid recursive test invocations.
- && ( ( --debug in $(argv) ) || ( --debug-module=$(m) in $(argv) ) )
- {
- .tested += $(m) ;
- if ! ( --quiet in $(argv) )
- {
- ECHO testing module $(m)... ;
- }
-
- # Import m's rules into __test-$(m)__ for easy access.
- IMPORT $(m) : [ RULENAMES $(m) ] : __test-$(m)__ : [ RULENAMES $(m) ] ;
-
- # Execute the module's __test__ rule in its own module to
- # eliminate the inadvertent effects of testing module
- # dependencies (such as assert) on the module itself.
- IMPORT $(m) : __test__ : __test-$(m)__ : __test__ : LOCALIZE ;
-
- module __test-$(m)__
- {
- # Set up the name of the module we're testing so that
- # no-test-defined can find it.
- __module__ = $(1) ;
- __test__ ;
- }
- }
+ run-module-test $(m) ;
}
.untested = ;
}
@@ -193,6 +204,7 @@
# This helper is used by load (above) to record the binding (path) of each
# loaded module.
+#
rule record-binding ( module-target : binding )
{
$(.loading[-1]).__binding__ = $(binding) ;
@@ -201,8 +213,9 @@
# Transform each path in the list, with all backslashes converted to forward
# slashes and all detectable redundancy removed. Something like this is probably
-# needed in path.jam, but I'm not sure of that, I don't understand it, and I'm
-# not ready to move all of path.jam into the kernel.
+# needed in path.jam, but I am not sure of that, I do not understand it, and I
+# am not ready to move all of path.jam into the kernel.
+#
local rule normalize-raw-paths ( paths * )
{
local result ;
@@ -224,6 +237,7 @@
# If rules-opt = '*', all rules from the indicated module are imported into the
# caller's module. If rename-opt is supplied, it must have the same number of
# elements as rules-opt.
+#
rule import ( module-names + : rules-opt * : rename-opt * )
{
if ( $(rules-opt) = * || ! $(rules-opt) ) && $(rename-opt)
@@ -288,10 +302,12 @@
}
}
+
# Define exported copies in $(target-module) of all rules exported from
# $(source-module). Also make them available in the global module with
# qualification, so that it is just as though the rules were defined originally
# in $(target-module).
+#
rule clone-rules ( source-module target-module )
{
local rules = [ RULENAMES $(source-module) ] ;
@@ -308,7 +324,7 @@
IMPORT modules : $(globalize) : : modules.$(globalize) ;
-local rule __test__ ( )
+rule __test__ ( )
{
import assert ;
import modules : normalize-raw-paths ;
Modified: branches/release/tools/build/v2/roll.sh
==============================================================================
--- branches/release/tools/build/v2/roll.sh (original)
+++ branches/release/tools/build/v2/roll.sh 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -50,7 +50,7 @@
chmod a+x jam_src/build.bat
cd .. && zip -r boost-build.zip boost-build && tar --bzip2 -cf boost-build.tar.bz2 boost-build
# Copy packages to a location where they are grabbed for beta.boost.org
-cp boost-build.zip boost-build.tar.bz2 ~/public_html/boost_build_nightly
+cp userman.pdf boost-build.zip boost-build.tar.bz2 ~/public_html/boost_build_nightly
cd boost-build
chmod -R u+w *
Modified: branches/release/tools/build/v2/test/BoostBuild.py
==============================================================================
--- branches/release/tools/build/v2/test/BoostBuild.py (original)
+++ branches/release/tools/build/v2/test/BoostBuild.py 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -139,14 +139,48 @@
def _status(self):
return self.status
+
class Tester(TestCmd.TestCmd):
- """Class for testing Boost.Build.
+ """Main tester class for Boost Build.
- Optional argument `executable` indicates the name of the executable to
- invoke. Set this to "jam" to test Boost.Build v1 behavior.
+ Optional arguments:
- Optional argument `work_dir` indicates an absolute directory, where the test
- will run be run.
+ `arguments` - Arguments passed to the run executable.
+ `executable` - Name of the executable to invoke.
+ `match` - Function to use for compating actual and
+ expected file contents.
+ `boost_build_path` - Boost build path to be passed to the run
+ executable.
+ `translate_suffixes` - Whether to update suffixes on the the file
+ names passed from the test script so they
+ match those actually created by the current
+ toolset. For example, static library files
+ are specified by using the .lib suffix but
+ when the 'gcc' toolset is used it actually
+ creates them using the .a suffix.
+ `pass_toolset` - Whether the test system should pass the
+ specified toolset to the run executable.
+ `use_test_config` - Whether the test system should tell the run
+ executable to read in the test_config.jam
+ configuration file.
+ `ignore_toolset_requirements` - Whether the test system should tell the run
+ executable to ignore toolset requirements.
+ `workdir` - indicates an absolute directory where the
+ test will be run from.
+
+ Optional arguments inherited from the base class:
+
+ `description` - Test description string displayed in case of
+ a failed test.
+ `subdir' - List of subdirectories to automatically
+ create under the working directory. Each
+ subdirectory needs to be specified
+ separately parent coming before its child.
+ `verbose` - Flag that may be used to enable more verbose
+ test system output. Note that it does not
+ also enable more verbose build system
+ output like the --verbose command line
+ option does.
"""
def __init__(self, arguments="", executable="bjam",
match=TestCmd.match_exact, boost_build_path=None,
@@ -157,7 +191,8 @@
if workdir != '' and not os.path.isabs(workdir):
raise "Parameter workdir <"+workdir+"> must point to an absolute directory: "
- self.last_build_time = 0
+ self.last_build_time_start = 0
+ self.last_build_time_finish = 0
self.translate_suffixes = translate_suffixes
self.use_test_config = use_test_config
@@ -186,7 +221,10 @@
elif os.uname()[0] == 'SunOS':
jam_build_dir = "bin.solaris"
elif os.uname()[0] == 'Darwin':
- jam_build_dir = "bin.macosxppc"
+ if os.uname()[4] == 'i386':
+ jam_build_dir = "bin.macosxx86"
+ else:
+ jam_build_dir = "bin.macosxppc"
elif os.uname()[0] == "AIX":
jam_build_dir = "bin.aix"
elif os.uname()[0] == "IRIX64":
@@ -218,7 +256,7 @@
verbosity = ['-d0', '--quiet']
if '--verbose' in sys.argv:
- keywords['verbose'] = 1
+ keywords['verbose'] = True
verbosity = ['-d+2']
if boost_build_path is None:
@@ -232,7 +270,7 @@
else:
program_list.append(os.path.join(jam_build_dir, executable))
inpath_bjam = None
- program_list.append('-sBOOST_BUILD_PATH=' + boost_build_path)
+ program_list.append('-sBOOST_BUILD_PATH="' + boost_build_path + '"')
if verbosity:
program_list += verbosity
if arguments:
@@ -253,7 +291,7 @@
TestCmd.TestCmd.cleanup(self)
os.chdir(self.original_workdir)
except AttributeError:
- # When this is called during by TestCmd.TestCmd.__del__ we can have
+ # When this is called during TestCmd.TestCmd.__del__ we can have
# both 'TestCmd' and 'os' unavailable in our scope. Do nothing in
# this case.
pass
@@ -262,7 +300,7 @@
# Methods that change the working directory's content.
#
def set_tree(self, tree_location):
- # Seems like it's not possible to remove the current a directory.
+ # It is not possible to remove the current directory.
d = os.getcwd()
os.chdir(os.path.dirname(self.workdir))
shutil.rmtree(self.workdir, ignore_errors=False)
@@ -281,7 +319,7 @@
os.path.walk(".", make_writable, None)
def write(self, file, content):
- self.wait_for_time_change()
+ self.wait_for_time_change_since_last_build()
nfile = self.native_file_name(file)
try:
os.makedirs(os.path.dirname(nfile))
@@ -304,7 +342,7 @@
self.touch(new);
def copy(self, src, dst):
- self.wait_for_time_change()
+ self.wait_for_time_change_since_last_build()
try:
self.write(dst, self.read(src, 1))
except:
@@ -318,12 +356,12 @@
os.utime(dst_name, (stats.st_atime, stats.st_mtime))
def touch(self, names):
- self.wait_for_time_change()
+ self.wait_for_time_change_since_last_build()
for name in self.adjust_names(names):
os.utime(self.native_file_name(name), None)
def rm(self, names):
- self.wait_for_time_change()
+ self.wait_for_time_change_since_last_build()
if not type(names) == types.ListType:
names = [names]
@@ -341,7 +379,7 @@
else:
os.unlink(n)
- # Create working dir root again, in case we've removed it.
+ # Create working dir root again in case we removed it.
if not os.path.exists(self.workdir):
os.mkdir(self.workdir)
os.chdir(self.workdir)
@@ -362,45 +400,50 @@
#
def run_build_system(self, extra_args="", subdir="", stdout=None, stderr="",
status=0, match=None, pass_toolset=None, use_test_config=None,
- ignore_toolset_requirements=None, **kw):
+ ignore_toolset_requirements=None, expected_duration=None, **kw):
- if os.path.isabs(subdir):
- if stderr:
- print "You must pass a relative directory to subdir <"+subdir+">."
- status = 1
- return
+ self.last_build_time_start = time.time()
- self.previous_tree = tree.build_tree(self.workdir)
+ try:
+ if os.path.isabs(subdir):
+ if stderr:
+ print "You must pass a relative directory to subdir <"+subdir+">."
+ status = 1
+ return
- if match is None:
- match = self.match
+ self.previous_tree = tree.build_tree(self.workdir)
- if pass_toolset is None:
- pass_toolset = self.pass_toolset
+ if match is None:
+ match = self.match
- if use_test_config is None:
- use_test_config = self.use_test_config
+ if pass_toolset is None:
+ pass_toolset = self.pass_toolset
- if ignore_toolset_requirements is None:
- ignore_toolset_requirements = self.ignore_toolset_requirements
+ if use_test_config is None:
+ use_test_config = self.use_test_config
- try:
- kw['program'] = []
- kw['program'] += self.program
- if extra_args:
- kw['program'] += extra_args.split(" ")
- if pass_toolset:
- kw['program'].append("toolset=" + self.toolset)
- if use_test_config:
- kw['program'].append('--test-config="%s"'
- % os.path.join(self.original_workdir, "test-config.jam"))
- if ignore_toolset_requirements:
- kw['program'].append("--ignore-toolset-requirements")
- kw['chdir'] = subdir
- apply(TestCmd.TestCmd.run, [self], kw)
- except:
- self.dump_stdio()
- raise
+ if ignore_toolset_requirements is None:
+ ignore_toolset_requirements = self.ignore_toolset_requirements
+
+ try:
+ kw['program'] = []
+ kw['program'] += self.program
+ if extra_args:
+ kw['program'] += extra_args.split(" ")
+ if pass_toolset:
+ kw['program'].append("toolset=" + self.toolset)
+ if use_test_config:
+ kw['program'].append('--test-config="%s"'
+ % os.path.join(self.original_workdir, "test-config.jam"))
+ if ignore_toolset_requirements:
+ kw['program'].append("--ignore-toolset-requirements")
+ kw['chdir'] = subdir
+ apply(TestCmd.TestCmd.run, [self], kw)
+ except:
+ self.dump_stdio()
+ raise
+ finally:
+ self.last_build_time_finish = time.time()
if status != None and _failed(self, status):
expect = ''
@@ -423,7 +466,7 @@
self.maybe_do_diff(self.stdout(), stdout)
self.fail_test(1, dump_stdio=False)
- # Intel tends to produce some message to stderr which makes tests fail.
+ # Intel tends to produce some messages to stderr which make tests fail.
intel_workaround = re.compile("^xi(link|lib): executing.*\n", re.M)
actual_stderr = re.sub(intel_workaround, "", self.stderr())
@@ -435,13 +478,19 @@
self.maybe_do_diff(actual_stderr, stderr)
self.fail_test(1, dump_stdio=False)
+ if not expected_duration is None:
+ actual_duration = self.last_build_time_finish - self.last_build_time_start
+ if ( actual_duration > expected_duration ):
+ print "Test run lasted %f seconds while it was expected to " \
+ "finish in under %f seconds." % (actual_duration,
+ expected_duration)
+ self.fail_test(1, dump_stdio=False)
+
self.tree = tree.build_tree(self.workdir)
self.difference = tree.trees_difference(self.previous_tree, self.tree)
self.difference.ignore_directories()
self.unexpected_difference = copy.deepcopy(self.difference)
- self.last_build_time = time.time()
-
def glob_file(self, name):
result = None
if hasattr(self,'difference'):
@@ -665,8 +714,11 @@
if exact:
matched = fnmatch.fnmatch(actual,content)
else:
- actual_ = map(lambda x: sorted(x.split()),actual.splitlines())
- content_ = map(lambda x: sorted(x.split()),content.splitlines())
+ def sorted_(x):
+ x.sort()
+ return x
+ actual_ = map(lambda x: sorted_(x.split()),actual.splitlines())
+ content_ = map(lambda x: sorted_(x.split()),content.splitlines())
if len(actual_) == len(content_):
matched = map(
lambda x,y: map(lambda n,p: fnmatch.fnmatch(n,p),x,y),
@@ -777,14 +829,14 @@
return os.path.normpath(apply(os.path.join, [self.workdir]+elements))
# Wait while time is no longer equal to the time last "run_build_system"
- # call finished.
- def wait_for_time_change(self):
+ # call finished. Used to avoid subsequent builds treating existing files as
+ # 'current'.
+ def wait_for_time_change_since_last_build(self):
while 1:
- f = time.time();
# In fact, I'm not sure why "+ 2" as opposed to "+ 1" is needed but
# empirically, "+ 1" sometimes causes 'touch' and other functions
# not to bump the file time enough for a rebuild to happen.
- if math.floor(f) < math.floor(self.last_build_time) + 2:
+ if math.floor(time.time()) < math.floor(self.last_build_time_finish) + 2:
time.sleep(0.1)
else:
break
Modified: branches/release/tools/build/v2/test/TestCmd.py
==============================================================================
--- branches/release/tools/build/v2/test/TestCmd.py (original)
+++ branches/release/tools/build/v2/test/TestCmd.py 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,28 +1,26 @@
"""
TestCmd.py: a testing framework for commands and scripts.
-The TestCmd module provides a framework for portable automated testing
-of executable commands and scripts (in any language, not just Python),
-especially commands and scripts that require file system interaction.
+The TestCmd module provides a framework for portable automated testing of
+executable commands and scripts (in any language, not just Python), especially
+commands and scripts that require file system interaction.
In addition to running tests and evaluating conditions, the TestCmd module
-manages and cleans up one or more temporary workspace directories, and
-provides methods for creating files and directories in those workspace
-directories from in-line data, here-documents), allowing tests to be
-completely self-contained.
+manages and cleans up one or more temporary workspace directories, and provides
+methods for creating files and directories in those workspace directories from
+in-line data, here-documents), allowing tests to be completely self-contained.
A TestCmd environment object is created via the usual invocation:
test = TestCmd()
-The TestCmd module provides pass_test(), fail_test(), and no_result()
-unbound methods that report test results for use with the Aegis change
-management system. These methods terminate the test immediately,
-reporting PASSED, FAILED, or NO RESULT respectively, and exiting with
-status 0 (success), 1 or 2 respectively. This allows for a distinction
-between an actual failed test and a test that could not be properly
-evaluated because of an external condition (such as a full file system
-or incorrect permissions).
+The TestCmd module provides pass_test(), fail_test(), and no_result() unbound
+methods that report test results for use with the Aegis change management
+system. These methods terminate the test immediately, reporting PASSED, FAILED
+or NO RESULT respectively and exiting with status 0 (success), 1 or 2
+respectively. This allows for a distinction between an actual failed test and a
+test that could not be properly evaluated because of an external condition (such
+as a full file system or incorrect permissions).
"""
# Copyright 2000 Steven Knight
@@ -67,6 +65,7 @@
import tempfile
import traceback
+
tempfile.template = 'testcmd.'
_Cleanup = []
@@ -81,6 +80,7 @@
sys.exitfunc = _clean
+
def caller(tblist, skip):
string = ""
arr = []
@@ -98,12 +98,13 @@
atfrom = "\tfrom"
return string
-def fail_test(self = None, condition = 1, function = None, skip = 0):
+
+def fail_test(self=None, condition=True, function=None, skip=0):
"""Cause the test to fail.
- By default, the fail_test() method reports that the test FAILED
- and exits with a status of 1. If a condition argument is supplied,
- the test fails only if the condition is true.
+ By default, the fail_test() method reports that the test FAILED and exits
+ with a status of 1. If a condition argument is supplied, the test fails only
+ if the condition is true.
"""
if not condition:
return
@@ -124,15 +125,15 @@
sys.stderr.write("FAILED test" + of + desc + sep + at + """
in directory: """ + os.getcwd() )
-
sys.exit(1)
-def no_result(self = None, condition = 1, function = None, skip = 0):
+
+def no_result(self=None, condition=True, function=None, skip=0):
"""Causes a test to exit with no valid result.
- By default, the no_result() method reports NO RESULT for the test
- and exits with a status of 2. If a condition argument is supplied,
- the test fails only if the condition is true.
+ By default, the no_result() method reports NO RESULT for the test and exits
+ with a status of 2. If a condition argument is supplied, the test fails only
+ if the condition is true.
"""
if not condition:
return
@@ -151,15 +152,15 @@
at = caller(traceback.extract_stack(), skip)
sys.stderr.write("NO RESULT for test" + of + desc + sep + at)
-
sys.exit(2)
-def pass_test(self = None, condition = 1, function = None):
+
+def pass_test(self=None, condition=True, function=None):
"""Causes a test to pass.
- By default, the pass_test() method reports PASSED for the test
- and exits with a status of 0. If a condition argument is supplied,
- the test passes only if the condition is true.
+ By default, the pass_test() method reports PASSED for the test and exits
+ with a status of 0. If a condition argument is supplied, the test passes
+ only if the condition is true.
"""
if not condition:
return
@@ -168,8 +169,10 @@
sys.stderr.write("PASSED\n")
sys.exit(0)
-def match_exact(lines = None, matches = None):
- """
+
+def match_exact(lines=None, matches=None):
+ """Returns whether the given lists or strings containing lines separated
+ using newline characters contain exactly the same data.
"""
if not type(lines) is ListType:
lines = split(lines, "\n")
@@ -182,8 +185,11 @@
return
return 1
-def match_re(lines = None, res = None):
- """
+
+def match_re(lines=None, res=None):
+ """Given lists or strings contain lines separated using newline characters.
+ This function matches those lines one by one, interpreting the lines in the
+ res parameter as regular expressions.
"""
if not type(lines) is ListType:
lines = split(lines, "\n")
@@ -196,25 +202,20 @@
return
return 1
+
class TestCmd:
- """Class TestCmd
+ """Class TestCmd.
"""
- def __init__(self, description = None,
- program = None,
- interpreter = None,
- workdir = None,
- subdir = None,
- verbose = 0,
- match = None,
- inpath = None):
+ def __init__(self, description=None, program=None, workdir=None,
+ subdir=None, verbose=False, match=None, inpath=None):
+
self._cwd = os.getcwd()
self.description_set(description)
if inpath:
self.program = program
else:
self.program_set(program)
- self.interpreter_set(interpreter)
self.verbose_set(verbose)
if not match is None:
self.match_func = match
@@ -252,20 +253,20 @@
def __repr__(self):
return "%x" % id(self)
- def cleanup(self, condition = None):
- """Removes any temporary working directories for the specified
- TestCmd environment. If the environment variable PRESERVE was
- set when the TestCmd environment was created, temporary working
- directories are not removed. If any of the environment variables
- PRESERVE_PASS, PRESERVE_FAIL, or PRESERVE_NO_RESULT were set
- when the TestCmd environment was created, then temporary working
- directories are not removed if the test passed, failed, or had
- no result, respectively. Temporary working directories are also
- preserved for conditions specified via the preserve method.
-
- Typically, this method is not called directly, but is used when
- the script exits to clean up temporary working directories as
- appropriate for the exit status.
+ def cleanup(self, condition=None):
+ """Removes any temporary working directories for the specified TestCmd
+ environment. If the environment variable PRESERVE was set when the
+ TestCmd environment was created, temporary working directories are not
+ removed. If any of the environment variables PRESERVE_PASS,
+ PRESERVE_FAIL or PRESERVE_NO_RESULT were set when the TestCmd
+ environment was created, then temporary working directories are not
+ removed if the test passed, failed or had no result, respectively.
+ Temporary working directories are also preserved for conditions
+ specified via the preserve method.
+
+ Typically, this method is not called directly, but is used when the
+ script exits to clean up temporary working directories as appropriate
+ for the exit status.
"""
if not self._dirlist:
return
@@ -280,10 +281,10 @@
for dir in list:
self.writable(dir, 1)
shutil.rmtree(dir, ignore_errors = 1)
-
+
self._dirlist = []
self.workdir = None
- os.chdir(self._cwd)
+ os.chdir(self._cwd)
try:
global _Cleanup
_Cleanup.remove(self)
@@ -295,11 +296,7 @@
"""
self.description = description
-# def diff(self):
-# """Diff two arrays.
-# """
-
- def fail_test(self, condition = 1, function = None, skip = 0):
+ def fail_test(self, condition=True, function=None, skip=0):
"""Cause the test to fail.
"""
if not condition:
@@ -310,12 +307,6 @@
function = function,
skip = skip)
- def interpreter_set(self, interpreter):
- """Set the program to be used to interpret the program
- under test as a script.
- """
- self.interpreter = interpreter
-
def match(self, lines, matches):
"""Compare actual and expected file contents.
"""
@@ -331,7 +322,7 @@
"""
return match_re(lines, res)
- def no_result(self, condition = 1, function = None, skip = 0):
+ def no_result(self, condition=True, function=None, skip=0):
"""Report that the test could not be run.
"""
if not condition:
@@ -342,7 +333,7 @@
function = function,
skip = skip)
- def pass_test(self, condition = 1, function = None):
+ def pass_test(self, condition=True, function=None):
"""Cause the test to pass.
"""
if not condition:
@@ -351,11 +342,10 @@
pass_test(self = self, condition = condition, function = function)
def preserve(self, *conditions):
- """Arrange for the temporary working directories for the
- specified TestCmd environment to be preserved for one or more
- conditions. If no conditions are specified, arranges for
- the temporary working directories to be preserved for all
- conditions.
+ """Arrange for the temporary working directories for the specified
+ TestCmd environment to be preserved for one or more conditions. If no
+ conditions are specified, arranges for the temporary working directories
+ to be preserved for all conditions.
"""
if conditions is ():
conditions = ('pass_test', 'fail_test', 'no_result')
@@ -369,13 +359,12 @@
program[0] = os.path.join(self._cwd, program[0])
self.program = program
- def read(self, file, mode = 'rb'):
- """Reads and returns the contents of the specified file name.
- The file name may be a list, in which case the elements are
- concatenated with the os.path.join() method. The file is
- assumed to be under the temporary working directory unless it
- is an absolute path name. The I/O mode for the file may
- be specified; it must begin with an 'r'. The default is
+ def read(self, file, mode='rb'):
+ """Reads and returns the contents of the specified file name. The file
+ name may be a list, in which case the elements are concatenated with the
+ os.path.join() method. The file is assumed to be under the temporary
+ working directory unless it is an absolute path name. The I/O mode for
+ the file may be specified; it must begin with an 'r'. The default is
'rb' (binary read).
"""
if type(file) is ListType:
@@ -386,14 +375,10 @@
raise ValueError, "mode must begin with 'r'"
return open(file, mode).read()
- def run(self, program = None,
- interpreter = None,
- arguments = None,
- chdir = None,
- stdin = None):
- """Runs a test of the program or script for the test
- environment. Standard output and error output are saved for
- future retrieval via the stdout() and stderr() methods.
+ def run(self, program=None, arguments=None, chdir=None, stdin=None):
+ """Runs a test of the program or script for the test environment.
+ Standard output and error output are saved for future retrieval via the
+ stdout() and stderr() methods.
"""
if chdir:
oldcwd = os.getcwd()
@@ -407,12 +392,8 @@
if program[0] != self.program[0] and not os.path.isabs(program[0]):
program[0] = os.path.join(self._cwd, program[0])
cmd += program
- # if interpreter:
- # cmd = interpreter + " " + cmd
else:
cmd += self.program
- # if self.interpreter:
- # cmd = self.interpreter + " " + cmd
if arguments:
cmd += arguments.split(" ")
if self.verbose:
@@ -420,7 +401,65 @@
try:
p = popen2.Popen3(cmd, 1)
except AttributeError:
- (tochild, fromchild, childerr) = os.popen3(join(cmd, " "))
+ # We end up here in case the popen2.Popen3 class is not available
+ # (e.g. on Windows). We will be using the os.popen3() Python API
+ # which takes a string parameter and so needs its executable quoted
+ # in case its name contains spaces.
+ cmd[0] = '"' + cmd[0] + '"'
+ command_string = join(cmd, " ")
+ if ( os.name == 'nt' ):
+ # This is a workaround for a longstanding Python bug on Windows
+ # when using os.popen(), os.system() and similar functions to
+ # execute a command containing quote characters. The bug seems
+ # to be related to the quote stripping functionality used by the
+ # Windows cmd.exe interpreter when its /S is not specified.
+ #
+ # Cleaned up quote from the cmd.exe help screen as displayed on
+ # Windows XP SP2:
+ #
+ # 1. If all of the following conditions are met, then quote
+ # characters on the command line are preserved:
+ #
+ # - no /S switch
+ # - exactly two quote characters
+ # - no special characters between the two quote
+ # characters, where special is one of: &<>()@^|
+ # - there are one or more whitespace characters between
+ # the two quote characters
+ # - the string between the two quote characters is the
+ # name of an executable file.
+ #
+ # 2. Otherwise, old behavior is to see if the first character
+ # is a quote character and if so, strip the leading
+ # character and remove the last quote character on the
+ # command line, preserving any text after the last quote
+ # character.
+ #
+ # This causes some commands containing quotes not to be executed
+ # correctly. For example:
+ #
+ # "\Long folder name\aaa.exe" --name="Jurko" --no-surname
+ #
+ # would get its outermost quotes stripped and would be executed
+ # as:
+ #
+ # \Long folder name\aaa.exe" --name="Jurko --no-surname
+ #
+ # which would report an error about '\Long' not being a valid
+ # command.
+ #
+ # cmd.exe help seems to indicate it would be enough to add an
+ # extra space character in front of the command to avoid this
+ # but this does not work, most likely due to the shell first
+ # stripping all leading whitespace characters from the command.
+ #
+ # Solution implemented here is to quote the whole command in
+ # case it contains any quote characters. Note thought this will
+ # not work correctly should Python ever fix this bug.
+ # (01.05.2008.) (Jurko)
+ if command_string.find('"') != -1:
+ command_string = '"' + command_string + '"'
+ (tochild, fromchild, childerr) = os.popen3(command_string)
if stdin:
if type(stdin) is ListType:
for line in stdin:
@@ -429,7 +468,7 @@
tochild.write(stdin)
tochild.close()
self._stdout.append(fromchild.read())
- self._stderr.append(childerr.read())
+ self._stderr.append(childerr.read())
fromchild.close()
self.status = childerr.close()
if not self.status:
@@ -447,20 +486,19 @@
self._stdout.append(p.fromchild.read())
self._stderr.append(p.childerr.read())
self.status = p.wait()
-
+
if self.verbose:
sys.stdout.write(self._stdout[-1])
sys.stderr.write(self._stderr[-1])
-
+
if chdir:
os.chdir(oldcwd)
- def stderr(self, run = None):
- """Returns the error output from the specified run number.
- If there is no specified run number, then returns the error
- output of the last run. If the run number is less than zero,
- then returns the error output from that many runs back from the
- current run.
+ def stderr(self, run=None):
+ """Returns the error output from the specified run number. If there is
+ no specified run number, then returns the error output of the last run.
+ If the run number is less than zero, then returns the error output from
+ that many runs back from the current run.
"""
if not run:
run = len(self._stderr)
@@ -471,12 +509,11 @@
return ''
return self._stderr[run]
- def stdout(self, run = None):
- """Returns the standard output from the specified run number.
- If there is no specified run number, then returns the standard
- output of the last run. If the run number is less than zero,
- then returns the standard output from that many runs back from
- the current run.
+ def stdout(self, run=None):
+ """Returns the standard output from the specified run number. If there
+ is no specified run number, then returns the standard output of the last
+ run. If the run number is less than zero, then returns the standard
+ output from that many runs back from the current run.
"""
if not run:
run = len(self._stdout)
@@ -488,11 +525,11 @@
return self._stdout[run]
def subdir(self, *subdirs):
- """Create new subdirectories under the temporary working
- directory, one for each argument. An argument may be a list,
- in which case the list elements are concatenated using the
- os.path.join() method. Subdirectories multiple levels deep
- must be created using a separate argument for each level:
+ """Create new subdirectories under the temporary working directory, one
+ for each argument. An argument may be a list, in which case the list
+ elements are concatenated using the os.path.join() method.
+ Subdirectories multiple levels deep must be created using a separate
+ argument for each level:
test.subdir('sub', ['sub', 'dir'], ['sub', 'dir', 'ectory'])
@@ -514,11 +551,10 @@
return count
def unlink (self, file):
- """Unlinks the specified file name.
- The file name may be a list, in which case the elements are
- concatenated with the os.path.join() method. The file is
- assumed to be under the temporary working directory unless it
- is an absolute path name.
+ """Unlinks the specified file name. The file name may be a list, in
+ which case the elements are concatenated using the os.path.join()
+ method. The file is assumed to be under the temporary working directory
+ unless it is an absolute path name.
"""
if type(file) is ListType:
file = apply(os.path.join, tuple(file))
@@ -526,16 +562,14 @@
file = os.path.join(self.workdir, file)
os.unlink(file)
-
def verbose_set(self, verbose):
"""Set the verbose level.
"""
self.verbose = verbose
def workdir_set(self, path):
- """Creates a temporary working directory with the specified
- path name. If the path is a null string (''), a unique
- directory name is created.
+ """Creates a temporary working directory with the specified path name.
+ If the path is a null string (''), a unique directory name is created.
"""
if os.path.isabs(path):
@@ -554,9 +588,9 @@
_Cleanup.append(self)
# We'd like to set self.workdir like this:
# self.workdir = path
- # But symlinks in the path will report things
- # differently from os.getcwd(), so chdir there
- # and back to fetch the canonical path.
+ # But symlinks in the path will report things differently from
+ # os.getcwd(), so chdir there and back to fetch the canonical
+ # path.
cwd = os.getcwd()
os.chdir(path)
self.workdir = os.getcwd()
@@ -565,16 +599,16 @@
self.workdir = None
def workpath(self, *args):
- """Returns the absolute path name to a subdirectory or file
- within the current temporary working directory. Concatenates
- the temporary working directory name with the specified
- arguments using the os.path.join() method.
+ """Returns the absolute path name to a subdirectory or file within the
+ current temporary working directory. Concatenates the temporary working
+ directory name with the specified arguments using the os.path.join()
+ method.
"""
return apply(os.path.join, (self.workdir,) + tuple(args))
def writable(self, top, write):
- """Make the specified directory tree writable (write == 1)
- or not (write == None).
+ """Make the specified directory tree writable (write == 1) or not
+ (write == None).
"""
def _walk_chmod(arg, dirname, names):
@@ -598,16 +632,15 @@
try:
os.path.walk(top, _walk_chmod, f)
except:
- pass # ignore any problems changing modes
+ pass # Ignore any problems changing modes.
- def write(self, file, content, mode = 'wb'):
- """Writes the specified content text (second argument) to the
- specified file name (first argument). The file name may be
- a list, in which case the elements are concatenated with the
- os.path.join() method. The file is created under the temporary
- working directory. Any subdirectories in the path must already
- exist. The I/O mode for the file may be specified; it must
- begin with a 'w'. The default is 'wb' (binary write).
+ def write(self, file, content, mode='wb'):
+ """Writes the specified content text (second argument) to the specified
+ file name (first argument). The file name may be a list, in which case
+ the elements are concatenated using the os.path.join() method. The file
+ is created under the temporary working directory. Any subdirectories in
+ the path must already exist. The I/O mode for the file may be specified;
+ it must begin with a 'w'. The default is 'wb' (binary write).
"""
if type(file) is ListType:
file = apply(os.path.join, tuple(file))
Modified: branches/release/tools/build/v2/test/build_file.py
==============================================================================
--- branches/release/tools/build/v2/test/build_file.py (original)
+++ branches/release/tools/build/v2/test/build_file.py 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,46 +1,170 @@
#!/usr/bin/python
# Copyright (C) Vladimir Prus 2006.
+# Copyright (C) Jurko Gospodnetic 2008.
# Distributed under the Boost Software License, Version 1.0. (See
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
-# Tests that we can build a file (not target), by it's name
-from BoostBuild import Tester, List
-from string import find
+# Tests that we explicitly request a file (not target) to be built by specifying
+# its name on the command line.
-# Create a temporary working directory
-t = Tester()
+import BoostBuild
-# Create the needed files
-t.write("Jamroot", """
+
+################################################################################
+#
+# test_building_file_from_specific_project()
+# ------------------------------------------
+#
+################################################################################
+
+def test_building_file_from_specific_project():
+ t = BoostBuild.Tester()
+
+ t.write("Jamroot.jam", """
exe hello : hello.cpp ;
+exe hello2 : hello.cpp ;
build-project sub ;
""")
-t.write("hello.cpp", """
-int main()
-{
- return 0;
-}
-""")
-t.write("sub/Jamfile", """
+ t.write("hello.cpp", "int main() { return 0; }")
+ t.write("sub/Jamfile.jam", """
exe hello : hello.cpp ;
+exe hello2 : hello.cpp ;
exe sub : hello.cpp ;
""")
-t.write("sub/hello.cpp", """
-int main()
-{
- return 0;
-}
-""")
+ t.write("sub/hello.cpp", "int main() { return 0; }")
+ t.run_build_system("sub " + t.adjust_suffix("hello.obj"))
+ t.expect_output_line("*depends on itself*", False)
+ t.expect_addition("sub/bin/$toolset/debug/hello.obj")
+ t.expect_nothing_more()
+
+ t.cleanup()
+
+
+################################################################################
+#
+# test_building_file_from_specific_target()
+# -----------------------------------------
+#
+################################################################################
+
+def test_building_file_from_specific_target():
+ t = BoostBuild.Tester()
+
+ t.write("Jamroot.jam", """
+exe hello1 : hello1.cpp ;
+exe hello2 : hello2.cpp ;
+exe hello3 : hello3.cpp ;
+""")
+ t.write("hello1.cpp", "int main() { return 0; }")
+ t.write("hello2.cpp", "int main() { return 0; }")
+ t.write("hello3.cpp", "int main() { return 0; }")
+
+ t.run_build_system("hello1 " + t.adjust_suffix("hello1.obj"))
+ t.expect_addition("bin/$toolset/debug/hello1.obj")
+ t.expect_nothing_more()
+
+ t.cleanup()
+
+
+################################################################################
+#
+# test_building_missing_file_from_specific_target()
+# -------------------------------------------------
+#
+################################################################################
+
+def test_building_missing_file_from_specific_target():
+ t = BoostBuild.Tester()
+
+ t.write("Jamroot.jam", """
+exe hello1 : hello1.cpp ;
+exe hello2 : hello2.cpp ;
+exe hello3 : hello3.cpp ;
+""")
+ t.write("hello1.cpp", "int main() { return 0; }")
+ t.write("hello2.cpp", "int main() { return 0; }")
+ t.write("hello3.cpp", "int main() { return 0; }")
+
+ t.run_build_system("hello1 " + t.adjust_suffix("hello2.obj"), status=1)
+ t.expect_output_line("don't know how to make*hello2.obj")
+ t.expect_nothing_more()
+
+ t.cleanup()
+
+
+################################################################################
+#
+# test_building_multiple_files_with_different_names()
+# ---------------------------------------------------
+#
+################################################################################
+
+def test_building_multiple_files_with_different_names():
+ t = BoostBuild.Tester()
+
+ t.write("Jamroot.jam", """
+exe hello1 : hello1.cpp ;
+exe hello2 : hello2.cpp ;
+exe hello3 : hello3.cpp ;
+""")
+ t.write("hello1.cpp", "int main() { return 0; }")
+ t.write("hello2.cpp", "int main() { return 0; }")
+ t.write("hello3.cpp", "int main() { return 0; }")
+
+ t.run_build_system(
+ t.adjust_suffix("hello1.obj") + " " +
+ t.adjust_suffix("hello2.obj"))
+ t.expect_addition("bin/$toolset/debug/hello1.obj")
+ t.expect_addition("bin/$toolset/debug/hello2.obj")
+ t.expect_nothing_more()
+
+ t.cleanup()
+
+
+################################################################################
+#
+# test_building_multiple_files_with_the_same_name()
+# -------------------------------------------------
+#
+################################################################################
-t.run_build_system(t.adjust_suffix("hello.obj"))
+def test_building_multiple_files_with_the_same_name():
+ t = BoostBuild.Tester()
-t.fail_test(find(t.stdout(), "depends on itself") != -1)
-t.expect_addition("bin/$toolset/debug/hello.obj")
-t.expect_addition("sub/bin/$toolset/debug/hello.obj")
-t.expect_nothing_more()
+ t.write("Jamroot.jam", """
+exe hello : hello.cpp ;
+exe hello2 : hello.cpp ;
+build-project sub ;
+""")
+ t.write("hello.cpp", "int main() { return 0; }")
+ t.write("sub/Jamfile.jam", """
+exe hello : hello.cpp ;
+exe hello2 : hello.cpp ;
+exe sub : hello.cpp ;
+""")
+ t.write("sub/hello.cpp", "int main() { return 0; }")
-# Remove temporary directories
-t.cleanup()
+ t.run_build_system(t.adjust_suffix("hello.obj"))
+ t.expect_output_line("*depends on itself*", False)
+ t.expect_addition("bin/$toolset/debug/hello.obj")
+ t.expect_addition("sub/bin/$toolset/debug/hello.obj")
+ t.expect_nothing_more()
+
+ t.cleanup()
+
+
+################################################################################
+#
+# main()
+# ------
+#
+################################################################################
+
+test_building_file_from_specific_project()
+test_building_file_from_specific_target()
+test_building_missing_file_from_specific_target()
+test_building_multiple_files_with_different_names()
+test_building_multiple_files_with_the_same_name()
Modified: branches/release/tools/build/v2/test/conditionals_multiple.py
==============================================================================
--- branches/release/tools/build/v2/test/conditionals_multiple.py (original)
+++ branches/release/tools/build/v2/test/conditionals_multiple.py 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -236,7 +236,7 @@
t.expect_output_line("description: /a0-t1-b0/", False)
t.expect_output_line("description: /a0-t1-b1/", False)
t.expect_output_line("description: /a1-t0-b0/", False)
- t.expect_output_line("description: /a1-t0-b1/", False)
+ t.expect_output_line("description: /a1-t0-b1/" )
t.expect_output_line("description: /b0-a1-t0/", False)
t.expect_output_line("description: /b0-a0-t1/", False)
t.expect_output_line("description: /b0-a1-t1/", False)
Modified: branches/release/tools/build/v2/test/example_qt4.py
==============================================================================
--- branches/release/tools/build/v2/test/example_qt4.py (original)
+++ branches/release/tools/build/v2/test/example_qt4.py 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -13,14 +13,14 @@
t.set_tree("../example/qt/qt4/hello")
t.run_build_system()
-t.expect_addition(["bin/$toolset/debug/threading-multi/user-interface-gui/arrow"])
+t.expect_addition(["bin/$toolset/debug/threading-multi/arrow"])
t.set_tree("../example/qt/qt4/moccable-cpp")
t.run_build_system()
-t.expect_addition(["bin/$toolset/debug/threading-multi/user-interface-gui/main"])
+t.expect_addition(["bin/$toolset/debug/threading-multi/main"])
t.set_tree("../example/qt/qt4/uic")
t.run_build_system()
-t.expect_addition(["bin/$toolset/debug/threading-multi/user-interface-gui/hello"])
+t.expect_addition(["bin/$toolset/debug/threading-multi/hello"])
t.cleanup()
Modified: branches/release/tools/build/v2/test/rebuilds.py
==============================================================================
--- branches/release/tools/build/v2/test/rebuilds.py (original)
+++ branches/release/tools/build/v2/test/rebuilds.py 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -35,7 +35,7 @@
t.expect_addition('bar')
t.expect_nothing_more()
-t.wait_for_time_change()
+t.wait_for_time_change_since_last_build()
t.run_build_system('-ffile.jam foo')
t.expect_touch('bar')
t.expect_addition('foo')
Modified: branches/release/tools/build/v2/test/test_all.py
==============================================================================
--- branches/release/tools/build/v2/test/test_all.py (original)
+++ branches/release/tools/build/v2/test/test_all.py 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -16,13 +16,13 @@
'BOOST_ROOT','BOOST_BUILD_PATH','JAM_TOOLSET','BCCROOT',
'MSVCDir','MSVC','MSVCNT','MINGW','watcom'
):
-
+
try:
del os.environ[s]
except:
pass
-BoostBuild.set_defer_annotations(1)
+BoostBuild.set_defer_annotations(1)
def run_tests(critical_tests, other_tests):
"""Runs first critical tests and then other_tests.
@@ -59,7 +59,7 @@
BoostBuild.flush_annotations();
pass_count = pass_count + 1
sys.stdout.flush() # makes testing under emacs more entertaining.
-
+
# Erase the file on success
if failures_count == 0:
open('test_results.txt', 'w')
@@ -69,7 +69,7 @@
PASS: %d
FAIL: %d
""" % (pass_count, failures_count)
-
+
def last_failed_test():
"Returns the name of last failed test or None"
@@ -87,7 +87,7 @@
except ValueError:
return tests
-
+
critical_tests = ["unit_tests", "module_actions", "startup_v1", "startup_v2"]
critical_tests += ["core_d12", "core_typecheck", "core_delete_module",
@@ -167,6 +167,8 @@
"example_make",
"remove_requirement",
"free_features_request",
+ "file_name_handling",
+ "sort_rule"
]
if os.name == 'posix':
@@ -187,13 +189,14 @@
if "--extras" in sys.argv:
tests.append("boostbook")
+ tests.append("qt4")
tests.append("example_qt4")
# Requires ./whatever.py to work, so is
# not guaranted to work everywhere.
tests.append("example_customization")
# Requires gettext tools.
tests.append("example_gettext")
-
+
else:
print 'Note: skipping extra tests'
Modified: branches/release/tools/build/v2/test/test_system.html
==============================================================================
--- branches/release/tools/build/v2/test/test_system.html (original)
+++ branches/release/tools/build/v2/test/test_system.html 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -12,14 +12,14 @@
<style type="text/css">
hr { color: black }
p.revision { text-align: right; font-style: italic }
- pre.code { margin-left: 2em }
- pre.example { margin-left: 2em; border: solid black thin }
+ pre.code { margin-left: 2em }
+ pre.example { margin-left: 2em; border: solid black thin }
pre.output { margin-left: 2em }
img.banner { border: 0; float: left }
h1 { text-align: right }
br.clear { clear: left }
div.attention { color: red }
-
+
</style>
</head>
@@ -34,6 +34,12 @@
<dl class="page-index">
<dt>Introduction for users</dt>
+ <dd>
+ <dl class="page-index">
+ <dt>Command line options</dt>
+ </dl>
+ </dd>
+
<dt>Introduction for developers</dt>
<dd>
@@ -41,8 +47,8 @@
<dt><a href="#sec-intro-changing">Changing the working
directory</a></dt>
- <dt><a href="#sec-intro-examining">Examining the working directory
- and changing it</a></dt>
+ <dt><a href="#sec-intro-examining">Examining the working directory and
+ changing it</a></dt>
<dt>Test result</dt>
</dl>
@@ -87,14 +93,13 @@
<h2><a name="sec-intro">Introduction for users</a></h2>
- <p>The testing system for Boost.Build is a small set of Python modules
- and scripts for automatically testing user-obversable behaviour. It uses
- components from testing systems of <a href=
- "http://www.scons.org">Scons</a> and <a href=
- "http://subversion.tigris.org">Subversion</a>, together with some
- additional functionality.</p>
+ <p>The testing system for Boost.Build is a small set of Python modules and
+ scripts for automatically testing user-obversable behaviour. It uses
+ components from testing systems of Scons
+ and Subversion, together with
+ some additional functionality.</p>
- <p>To run the tests you'd need:</p>
+ <p>To run the tests you need to:</p>
<ol>
<li>Get the source tree of Boost.Build (located at <tt>tools/build</tt>
@@ -115,24 +120,46 @@
for testing.</li>
</ol>
- <p>When all is done, you can run the tests with</p>
+ <p>When all is set, you can run all the tests using the <tt>test_all.py</tt>
+ script or you can run a specific test by starting its Python script
+ directly.</p>
+
+ <p>Examples:</p>
+
<pre class="code">
python test_all.py
+python generators_test.py
</pre>
- <p>which will use the default toolset, or you can specify toolset on the
- command line, for example:</p>
+ <p>If everything is OK, you will see a list of passed tests. Otherwise, a
+ failure will be reported.</p>
+
+ <h3><a name="sec-command-line-options">Command line options</a></h3>
+
+ <p>Test scripts will use the toolset you configured to be the default or
+ you can specify a specific one on the command line:</p>
+
<pre class="code">
python test_all.py borland
+python generators_test.py msvc-7.1
</pre>
- <p>If everything's OK, you'll see a list of passed tests. Otherwise, a
- failure will be reported.</p>
+ <p>Other test script flags you can specify on the command line are:</p>
- <p>It is possible to run a specific test, for example:</p>
-<pre class="code">
-python generators_test.py
-</pre>
+ <ul>
+ <li><tt>--default-bjam</tt> -- By default the test system will use the
+ Boost Jam executable found built in its default development build
+ location. This option makes it use the default one available on your
+ system, i.e. the one found in the system path.</li>
+
+ <li><tt>--preserve</tt> -- In case of a failed test its working
+ directory will be copied to the "failed_test" directory under the
+ current directory.</li>
+
+ <li><tt>--verbose</tt> -- Makes the test system and the run build system
+ display additional output. Note though that this may cause tests that
+ check the build system output to fail.</li>
+ </ul>
<h2><a name="sec-developers">Introduction for developers</a></h2>
@@ -144,28 +171,28 @@
<li>For an interpreted language like Jam, without any static checks,
testing is simply the only sefeguard we can have.</li>
- <li>Good tests allow to change internal design much more safely, and we
- didn't nailed everything down yet.</li>
+ <li>Good tests allow us to change internal design much more safely, and we
+ have not gotten everything nailed down yet.</li>
</ul>
<p>Adding a new test is simple:</p>
<ol>
<li>Go to <tt>$boost_build_root/test/test_all.py</tt> and add new test
- name to the list at the end of file. Suppose the test name is
- "hello".</li>
+ name to the list at the end of the file. Suppose the test name is "hello".
+ </li>
- <li>Add a new python module, in this example "hello.py", to do actual
+ <li>Add a new python module, in this example "hello.py", to do the actual
testing.</li>
</ol>
<p>The module, in general will perform these basic actions:</p>
<ol>
- <li>Setting the initial working directory state</li>
+ <li>Set up the initial working directory state</li>
<li>
- Running the build system and checking:
+ Run the build system and check the results:
<ol>
<li>generated output,</li>
@@ -176,10 +203,10 @@
</ol>
</li>
- <li>Adding, removing or touching files, or changing their content and
- then repeating the previous step, until satisfied.</li>
+ <li>Add, remove or touch files or change their content and then repeat
+ the previous step until satisfied.</li>
- <li>Cleaning up</li>
+ <li>Clean up</li>
</ol>
<p>The "hello.py" module might contain:</p>
@@ -204,12 +231,12 @@
t.run_build_system()
-# First, create a list of three pathnames
+# First, create a list of three pathnames.
file_list = List("bin/$toolset/debug/") * List("hello.exe hello.obj")
# Second, assert that those files were added as result of the last build system invocation.
t.expect_addition(file_list)
-# Invoke the build system once again
+# Invoke the build system once again.
t.run_build_system("clean")
# Check if the files added previously were removed.
t.expect_removal(file_list)
@@ -221,18 +248,18 @@
<p>The <tt>test</tt> directory contains a file "template.py" which can be
used as a start for your own tests.</p>
- <p>Overview of the most important methods of class
- <tt>TestBoostBuild</tt> follows.</p>
+ <p>Overview of the most important methods of class <tt>Tester</tt> follows.
+ </p>
<h3><a name="sec-intro-changing">Changing the working directory</a></h3>
- <p>The class <tt>TestBoostBuild</tt> creates a temporary directory in its
+ <p>The class <tt>Tester</tt> creates a temporary directory in its
constructor and changes to that directory. It can be modified by calling
these methods:</p>
<ul>
- <li><tt>set_tree</tt> -- sets the content of the working directory to
- be equal to the content of the specified directory. This method is
+ <li><tt>set_tree</tt> -- sets the content of the working directory to be
+ equal to the content of the specified directory. This method is
preferrable when directory tree for testing is large.</li>
<li><tt>write</tt> -- sets the content of file in a working directory.
@@ -245,28 +272,27 @@
<h3><a name="sec-intro-examining">Examining the working directory and
changing it</a></h3>
- <p>The method <tt>read</tt>, inherited from the <tt>TestCmd</tt> class,
- can be used to read any file in the working directory and check its
- content. <tt>TestBoostBuild</tt> adds another method for tracking
- changes. Whenever build system is run (via <tt>run_build_system</tt>),
- the state of working dir before and after running is recorded. In
- addition, difference between the two states -- i.e. lists of files that
- were added, removed, modified or touched -- is stored in two member
- variables, <tt>tree_difference</tt> and
- <tt>unexpected_difference</tt>.</p>
-
- <p>After than, the test author may specify that some change is expected,
- for example, by calling <tt>expect_addition("foo")</tt>. This call will
- check if the file was indeed added, and if so, will remove its name from
- the list of added files in <tt>unexpected_difference</tt>. Likewise, it's
- possible to specify that some changes are not interesting, for example a
- call <tt>ignore("*.obj")</tt> will just remove every files with ".obj"
+ <p>The method <tt>read</tt>, inherited from the <tt>TestCmd</tt> class, can
+ be used to read any file in the working directory and check its content.
+ <tt>Tester</tt> adds another method for tracking changes. Whenever the build
+ system is run (using <a href="#method-run_build_system"><tt>run_build_system
+ </tt></a>), the working dir state before and after running is recorded. In
+ addition, difference between the two states -- i.e. lists of files that were
+ added, removed, modified or touched -- are stored in two member variables -
+ <tt>tree_difference</tt> and <tt>unexpected_difference</tt>.</p>
+
+ <p>After than, the test author may specify that some change is expected, for
+ example, by calling <tt>expect_addition("foo")</tt>. This call will check if
+ the file was indeed added, and if so, will remove its name from the list of
+ added files in <tt>unexpected_difference</tt>. Likewise, it is possible to
+ specify that some changes are not interesting, for example a call to
+ <tt>ignore("*.obj")</tt> will just remove every file with the ".obj"
extension from <tt>unexpected_difference</tt>.</p>
<p>When test has finished with expectations and ignoring, the member
- <tt>unexpected_difference</tt> will contain the list of all changes not
- yet accounted for. It is possible to assure that this list is empty by
- calling <tt>expect_nothing_more</tt> member function.</p>
+ <tt>unexpected_difference</tt> will contain the list of all changes not yet
+ accounted for. It is possible to assure that this list is empty by calling
+ the <tt>expect_nothing_more</tt> member function.</p>
<h3><a name="sec-intro-results">Test result</a></h3>
@@ -277,24 +303,74 @@
<tt>pass_test</tt> and <tt>fail_test</tt> are used to explicitly give the
test outcome.</p>
- <p>Typically, after test termination, the working directory is erased. To
- debug a failed test, you should add "--preserve" option when invoking
- test. On failure, the working directory will be copied to "failed_test"
- directory in the current dir.</p>
+ <p>Typically, after test termination, the working directory is erased. See
+ the "--preserve" command line option
+ for information on how to preserve the working directory content for failed
+ tests for debugging purposes.</p>
<h2 id="sec-reference">Reference documentation</h2>
<p>The test system is composed of class <tt>Tester</tt>, derived form
- <tt>TestCmd.TestCmd</tt>, and helper class <tt>List</tt>. The methods of
- <tt>Tester</tt>, and the class <tt>List</tt> are described below.</p>
+ <tt>TestCmd.TestCmd</tt>, and helper class <tt>List</tt>. <tt>Tester</tt>
+ and <tt>List</tt> methods are described below.</p>
- <p>The documentation frequently refer to filename. In all cases, files
- are specified in unix style: a sequence of components, separated by "/".
- This is true on all platforms. In some contexts, a list of files is
- allowed. In that case any object with sequence interface is allowed.</p>
+ <p>The documentation frequently refers to <tt>filename</tt>. In all cases,
+ files are specified in unix style: a sequence of components, separated by
+ "/". This is true on all platforms. In some contexts a list of files is
+ allowed. In those cases any object with a sequence interface is allowed.</p>
+
+ <h3><a name="method-__init__">Method <tt>__init__(self, arguments="",
+ executable="bjam", match=TestCmd.match_exact, boost_build_path=None,
+ translate_suffixes=True, pass_toolset=True, use_test_config=True,
+ ignore_toolset_requirements=True, workdir="", **keywords)</tt></a></h3>
- <h3><a name="method-__init__">Method <tt>__init__(self, workdir='',
- arguments='', executable='bjam')</tt></a></h3>
+ <p><b>Optional arguments:</b></p>
+
+ <ul>
+ <li><tt>arguments</tt>
+ -- Arguments passed to the run executable.</li>
+ <li><tt>executable</tt>
+ -- Name of the executable to invoke.</li>
+ <li><tt>match</tt>
+ -- Function to use for compating actual and expected file contents.
+ </li>
+ <li><tt>boost_build_path</tt>
+ -- Boost build path to be passed to the run executable.</li>
+ <li><tt>translate_suffixes</tt>
+ -- Whether to update suffixes on the the file names passed from the
+ test script so they match those actually created by the current
+ toolset. For example, static library files are specified by using
+ the .lib suffix but when the 'gcc' toolset is used it actually
+ creates them using the .a suffix.</li>
+ <li><tt>pass_toolset</tt>
+ -- Whether the test system should pass the specified toolset to the
+ run executable.</li>
+ <li><tt>use_test_config</tt>
+ -- Whether the test system should tell the run executable to read in
+ the test_config.jam configuration file.</li>
+ <li><tt>ignore_toolset_requirements</tt>
+ -- Whether the test system should tell the run executable to ignore
+ toolset requirements.</li>
+ <li><tt>workdir</tt>
+ -- Indicates an absolute directory where the test will be run from.
+ </li>
+ </ul>
+
+ <p><b>Optional arguments inherited from the base class:</b></p>
+
+ <ul>
+ <li><tt>description</tt>
+ -- Test description string displayed in case of a failed test.</li>
+ <li><tt>subdir</tt>
+ -- List of subdirectories to automatically create under the working
+ directory. Each subdirectory needs to be specified separately
+ parent coming before its child.</li>
+ <li><tt>verbose</tt>
+ -- Flag that may be used to enable more verbose test system output.
+ Note that it does not also enable more verbose build system output
+ like the <a href="#sec-command-line-options">"--verbose" command
+ line option</a> does.</li>
+ </ul>
<p><b>Effects:</b></p>
@@ -302,20 +378,23 @@
<li>Remembers the current working directory in member
<tt>original_workdir</tt>.</li>
- <li>Determines the location of executable (<code>bjam</code> by
+ <li>Determines the location of the executable (<code>bjam</code> by
default) and build system files, assuming that the current directory is
<tt>tools/build/test</tt>. Formulates jam invocation command, which
- will include explicit setting for <tt>BOOST_BUILD_PATH</tt> variable
+ will include explicit setting for the <tt>BOOST_BUILD_PATH</tt> variable
and arguments passed to this methods, if any. This command will be used
- by subsequent invocation of <a href=
- "#method-run_build_system"><tt>run_build_system</tt></a>. Finally,
- initializes the base class.</li>
+ by subsequent invocation of <a href="#method-run_build_system"><tt>
+ run_build_system</tt></a>. Finally, initializes the base class.</li>
- <li>Changes current working dir to the temporary working directory
- created by the base constructor.</li>
+ <li>Changes the current working directory to the temporary working
+ directory created by the base constructor.</li>
- <li>If you want to run a test in a existing directory, pass it to
+ <li>If you want to run a test in an existing directory, pass it as
<tt>workdir</tt>.</li>
+
+ <li> Most parameters passed to this constructor function may be overruled
+ for each specific test system run using <a href=
+ "#method-run_build_system"><tt>run_build_system</tt></a> parameters.
</ol>
<h3><a name="method-set_tree">Method <tt>set_tree(self,
@@ -348,13 +427,14 @@
<p><b>Effects:</b></p>
- <p>Sets the access and modification times for all files in <tt>names</tt>
- to the current time. All the elements in <tt>names</tt> should be
- relative paths.</p>
+ <p>Sets the access and modification times for all files in <tt>names</tt> to
+ the current time. All the elements in <tt>names</tt> should be relative
+ paths.</p>
<h3><a name="method-run_build_system">Method <tt>run_build_system(self,
- subdir='', extra_args='', stdout=None, stderr='', status=0,
- **kw)</tt></a></h3>
+ extra_args="", subdir="", stdout=None, stderr="", status=0, match=None,
+ pass_toolset=None, use_test_config=None, ignore_toolset_requirements=None,
+ expected_duration=None, **kw)</tt></a></h3>
<p><b>Effects:</b></p>
@@ -375,18 +455,18 @@
invocation with values to appropriate parameters, if they are not
<tt>None</tt>. If any difference is found, the test fails.</li>
- <li>
- <p>Stores the new state of the working directory in
- <tt>self.tree</tt>. Computes the difference between previous and
- current trees and store them in variables
- <tt>self.tree_difference</tt> and
- <tt>self.unexpected_difference</tt>.</p>
-
- <p>Both variables are instances of class
- <tt>tree.Trees_different</tt>, which have four attributes:
- <tt>added_files</tt>, <tt>removed_files</tt>, <tt>modified_files</tt>
- and <tt>touched_files</tt>. Each is a list of strings.</p>
- </li>
+ <li>If the <tt>expected_duration</tt> parameter is specified then it
+ represents the maximal allowed time in seconds for the test to run. The
+ test will be marked as failed if its duration is greater than the given
+ <tt>expected_duration</tt> parameter value.</li>
+
+ <li>Stores the new state of the working directory in <tt>self.tree</tt>.
+ Computes the difference between previous and current trees and stores them
+ in variables <tt>self.tree_difference</tt> and
+ <tt>self.unexpected_difference</tt>. Both variables are instances of class
+ <tt>tree.Trees_different</tt>, which have four attributes:
+ <tt>added_files</tt>, <tt>removed_files</tt>, <tt>modified_files</tt> and
+ <tt>touched_files</tt>. Each is a list of strings.</p></li>
</ol>
<h3><a name="method-read">Method <tt>read(self, name)</tt></a></h3>
@@ -396,104 +476,95 @@
<p>Read the specified file and returns it content. Raises an exception is
the file is absent.</p>
- <h3><a name="method-read_and_strip">Method <tt>read_and_strip(self,
- name)</tt></a></h3>
+ <h3><a name="method-read_and_strip">Method <tt>read_and_strip(self, name)
+ </tt></a></h3>
<p><b>Effects:</b></p>
- <p>Read the specified file and returns it content, after removing
- trailing whitespace from every line. Raises an exception is the file is
- absent.</p>
+ <p>Read the specified file and returns it content, after removing trailing
+ whitespace from every line. Raises an exception is the file is absent.</p>
<p><b>Rationale:</b></p>
- <p>Althought this method is questionable, there are a lot of cases when
- jam or shells it uses insert spaces. It seems that introducing this
- method is much simpler than dealing with all those cases.</p>
-
- <h3><a name="methods-expectations">Methods for declaring
- expectations</a></h3>
-
- <p>Accordingly to the number of changes kinds that are detected, there
- are four methods that specify that test author expects a specific change
- to occur. They check <tt>self.unexpected_difference</tt>, and if the
- change is present there, it is removed. Otherwise, test fails.</p>
+ <p>Althought this method is questionable, there are a lot of cases when jam
+ or shells it uses insert spaces. It seems that introducing this method is
+ much simpler than dealing with all those cases.</p>
+
+ <h3><a name="methods-expectations">Methods for declaring expectations</a>
+ </h3>
+
+ <p>Accordingly to the number of changes kinds that are detected, there are
+ four methods that specify that test author expects a specific change to
+ occur. They check <tt>self.unexpected_difference</tt>, and if the change is
+ present there, it is removed. Otherwise, test fails.</p>
<p>Each method accepts a list of names. Those names use <tt>/</tt> path
- separator on all systems. Additionaly, the test system translates
- suffixes appropriately. For the test to be portable, suffixes should use
- Windows convention: <tt>exe</tt> for executables, <tt>dll</tt> for
- dynamic libraries and <tt>lib</tt> for static libraries. Lastly, the
- string "$toolset" in file names is replaced by the name of tested
- toolset.</p>
+ separator on all systems. Additionaly, the test system translates suffixes
+ appropriately. For the test to be portable, suffixes should use Windows
+ convention: <tt>exe</tt> for executables, <tt>dll</tt> for dynamic libraries
+ and <tt>lib</tt> for static libraries. Lastly, the string "$toolset" in file
+ names is replaced by the name of tested toolset.</p>
<p><b>Note:</b> The <tt>List</tt> helper class might be useful to create
lists of names.</p>
- <p><b>Note:</b> The file content can be examined using
+ <p><b>Note:</b> The file content can be examined using the
<tt>TestCmd.read</tt> function.</p>
<p>The members are:</p>
<ul>
<li>expect_addition</li>
-
<li>expect_removal</li>
-
<li>expect_modification</li>
-
<li>expect_nothing</li>
</ul>
<p>Note that <tt>expect_modification</tt> is used to check that a either
- file content or timestamp has changed. The rationale is that some
- compilers change content even if sources does not change, and it's easier
- to have a method which checks for both content and time changes.</p>
+ file content or timestamp has changed. The rationale is that some compilers
+ change content even if sources does not change, and it's easier to have a
+ method which checks for both content and time changes.</p>
- <p>There's also a member <tt>expect_nothing_more</tt>, which checks that
- all the changes are either expected or ignored, in other words that
+ <p>There's also a member <tt>expect_nothing_more</tt>, which checks that all
+ the changes are either expected or ignored, in other words that
<tt>unexpected_difference</tt> is empty by now.</p>
- <p>Lastly, there's a method to compare file content with expected
- content:</p>
- <tt>expect_content(self, name, content, exact=0)</tt>
+ <p>Lastly, there's a method to compare file content with expected content:
+ </p>
+ <tt>expect_content(self, name, content, exact=0)</tt>
- <p>The method fails the test if the content of file identified by 'name'
- is different from 'content'. If 'exact' is true, the file content is used
+ <p>The method fails the test if the content of file identified by 'name' is
+ different from 'content'. If 'exact' is true, the file content is used
as-is, otherwise, two transformations are applied:</p>
<ul>
<li>The <tt>read_and_strip</tt> method is used to read the file, which
removes trailing whitespace</li>
- <li>Each backslash in the file content is converted to forward
- slash.</li>
+ <li>Each backslash in the file content is converted to forward slash.</li>
</ul>
<h3><a name="methods-ignoring">Methods for ignoring changes</a></h3>
<p>There are five methods which ignore changes made to the working tree.
- They silently remove elements from <tt>self.unexpected_difference</tt>,
- and don't generate error if element is not found. They accept shell style
+ They silently remove elements from <tt>self.unexpected_difference</tt>, and
+ don't generate error if element is not found. They accept shell style
wildcard.</p>
<p>The following methods correspond to four kinds of changes:</p>
<ul>
<li>ignore_addition(self, wildcard)</li>
-
<li>ignore_removal(self, wildcard)</li>
-
<li>ignore_modification(self, wildcard)</li>
-
<li>ignore_touch(self, wilcard)</li>
</ul>
- <p>The method <tt>ignore(self, wildcard)</tt> ignores all the changes
- made to files that match a wildcard.</p>
+ <p>The method <tt>ignore(self, wildcard)</tt> ignores all the changes made
+ to files that match a wildcard.</p>
- <h3><a name="methods-result">Methods for explicitly specifying
- results</a></h3>
+ <h3><a name="methods-result">Methods for explicitly specifying results</a>
+ </h3>
<h4>Method <tt>pass_test(self, condition=1)</tt></h4>
@@ -503,51 +574,46 @@
<h4>Method <tt>fail_test(self, condition=1)</tt></h4>
- <p><b>Effects:</b> Cause the test to fail if <tt>condition</tt> is
- true.</p>
+ <p><b>Effects:</b> Cause the test to fail if <tt>condition</tt> is true.</p>
<h3><a name="class-list">Helper class <tt>List</tt></a></h3>
- The class has sequence interface and two additional methods.
+ The class has sequence interface and two additional methods.
<h4>Method <tt>__init__(self, string)</tt></h4>
- <p><b>Effects:</b> Splits the string on unescaped spaces and tabs. The
- split components can further be retrieved using standard sequence
- access.</p>
+ <p><b>Effects:</b> Splits the string on unescaped spaces and tabs. The split
+ components can further be retrieved using standard sequence access.</p>
<h4>Method <tt>__mul__(self, other)</tt></h4>
- <p><b>Effects:</b> Returns an <tt>List</tt> instance, which elements are
- all possible concatenations of two string, first of which is from
- <tt>self</tt>, and second of which is from <tt>other</tt>.</p>
+ <p><b>Effects:</b> Returns an <tt>List</tt> instance, which elements are all
+ possible concatenations of two string, first of which is from <tt>self</tt>,
+ and second of which is from <tt>other</tt>.</p>
<p>The class also defines <tt>__str__</tt> and <tt>__repr__</tt> methods.
- Finally, there's <tt>__coerce__</tt> method which allows to convert
- strings to instances of <tt>List</tt>.</p>
+ Finally, there's <tt>__coerce__</tt> method which allows to convert strings
+ to instances of <tt>List</tt>.</p>
<p><b>Example:</b></p>
<pre>
l = "a b" * List("c d")
for e in l:
- print e
-
+ print e
</pre>
- <p>will output</p>
+ <p>will output:</p>
<pre>
ac
ad
bc
bd
-
+
</pre>
<hr>
-
- <p class="revision">Last modified: Mar 11, 2005</p>
-
- <p>© Copyright Vladimir Prus 2002, 2003, 2004, 2005.
+ <p class="revision">Last modified: May 02, 2008</p>
+ <p>© Copyright Vladimir Prus 2002, 2003, 2004, 2005.<br>
+ © Copyright Jurko Gospodnetic 2008.<br>
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)</p>
</body>
</html>
-
Modified: branches/release/tools/build/v2/test/unit_test.py
==============================================================================
--- branches/release/tools/build/v2/test/unit_test.py (original)
+++ branches/release/tools/build/v2/test/unit_test.py 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -5,18 +5,17 @@
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
# Test the unit_test rule
-from BoostBuild import Tester, List
+import BoostBuild
-t = Tester()
+t = BoostBuild.Tester()
-# Create the needed files
-t.write("project-root.jam", """
+# Create the needed files.
+t.write("Jamroot.jam", """
using testing ;
-""")
-t.write("Jamfile", """
lib helper : helper.cpp ;
unit-test test : test.cpp : <library>helper ;
""")
+
t.write("test.cpp", """
void helper();
int main()
@@ -37,7 +36,4 @@
t.run_build_system("link=static")
t.expect_addition("bin/$toolset/debug/link-static/test.passed")
-
-
-
t.cleanup()
Modified: branches/release/tools/build/v2/tools/acc.jam
==============================================================================
--- branches/release/tools/build/v2/tools/acc.jam (original)
+++ branches/release/tools/build/v2/tools/acc.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -86,9 +86,10 @@
$(CONFIG_COMMAND) -AA $(LINKFLAGS) -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) $(OPTIONS)
}
+SPACE = " " ;
actions acc.link.dll bind NEEDLIBS
{
- $(CONFIG_COMMAND) -AA -b $(LINKFLAGS) -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) $(OPTIONS)
+ $(CONFIG_COMMAND) -AA -b $(LINKFLAGS) -o "$(<[1])" -Wl,+h$(SPACE)-Wl,$(<[-1]:D=) -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) $(OPTIONS)
}
actions acc.compile.c
Modified: branches/release/tools/build/v2/tools/builtin.jam
==============================================================================
--- branches/release/tools/build/v2/tools/builtin.jam (original)
+++ branches/release/tools/build/v2/tools/builtin.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -29,7 +29,7 @@
import types/register ;
-.os-names = amiga aix bsd cygwin darwin dos emx freebsd hpux linux netbsd
+.os-names = amiga aix bsd cygwin darwin dos emx freebsd hpux iphone linux netbsd
openbsd osf qnx qnxnto sgi solaris sun sunos svr4 sysv ultrix unix unixware
vms windows ;
@@ -42,6 +42,7 @@
# Translates from bjam current OS to the os tags used in host-os and target-os,
# i.e. returns the running host-os.
+#
local rule default-host-os ( )
{
local host-os ;
@@ -206,6 +207,9 @@
# HP/PA-RISC
parisc
+
+ # Advanced RISC Machines
+ arm
# Combined architectures for platforms/toolsets that support building for
# multiple architectures at once. "combined" would be the default multi-arch
@@ -243,6 +247,9 @@
# HP/PA-RISC
700 7100 7100lc 7200 7300 8000
+
+ # Advanced RISC Machines
+ armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te armv6 armv6j iwmmxt ep9312
: propagated optional ;
@@ -272,6 +279,7 @@
#
# Lastly, makes appropriate value of 'variant' property expand to the full
# property set.
+#
rule variant ( name # Name of the variant
: parents-or-properties * # Specifies parent variants, if
# 'explicit-properties' are given, and
@@ -437,15 +445,14 @@
scanner.register c-scanner : include ;
-# It most cases where a CPP file or a H file is a source of some action,
-# we should rebuild the result if any of files included by CPP/H
-# are changed. One case when this is not needed is installation,
-# which is handled specifically.
+# It most cases where a CPP file or a H file is a source of some action, we
+# should rebuild the result if any of files included by CPP/H are changed. One
+# case when this is not needed is installation, which is handled specifically.
type.set-scanner CPP : c-scanner ;
type.set-scanner C : c-scanner ;
-# One case where scanning of H/HPP files is necessary is PCH generation --
-# if any header included by HPP being precompiled changes, we need to
-# recompile the header.
+# One case where scanning of H/HPP files is necessary is PCH generation -- if
+# any header included by HPP being precompiled changes, we need to recompile the
+# header.
type.set-scanner H : c-scanner ;
type.set-scanner HPP : c-scanner ;
@@ -453,6 +460,7 @@
# The generator class for libraries (target type LIB). Depending on properties
# it will request building of the appropriate specific library type --
# -- SHARED_LIB, STATIC_LIB or SHARED_LIB.
+#
class lib-generator : generator
{
rule __init__ ( * : * )
@@ -509,6 +517,7 @@
# The implementation of the 'lib' rule. Beyond standard syntax that rule allows
# simplified: "lib a b c ;".
+#
rule lib ( names + : sources * : requirements * : default-build *
: usage-requirements * )
{
@@ -634,6 +643,7 @@
# For all virtual targets for the same dependency graph as self, i.e. which
# belong to the same main target, add their directories to the include path.
+ #
rule adjust-properties ( property-set )
{
local s = [ $(self.targets[1]).creating-subvariant ] ;
@@ -647,6 +657,7 @@
# type used to represent 'action' in the constructed dependency graph to
# 'compile-action'. That class in turn adds additional include paths to handle
# cases when a source file includes headers which are generated themselves.
+#
class C-compiling-generator : generator
{
rule __init__ ( id : source-types + : target-types + : requirements *
@@ -673,10 +684,12 @@
# FIXME: this is ugly, should find a better way (we'd like client code to
# register all generators as "generators.some-rule" instead of
# "some-module.some-rule".)
+#
IMPORT $(__name__) : register-c-compiler : : generators.register-c-compiler ;
# The generator class for handling EXE and SHARED_LIB creation.
+#
class linking-generator : generator
{
import path ;
@@ -848,6 +861,7 @@
# The generator class for handling STATIC_LIB creation.
+#
class archive-generator : generator
{
import property-set ;
@@ -912,6 +926,7 @@
# Generator that accepts everything and produces nothing. Useful as a general
# fallback for toolset-specific actions like PCH generation.
+#
class dummy-generator : generator
{
import property-set ;
Modified: branches/release/tools/build/v2/tools/common.jam
==============================================================================
--- branches/release/tools/build/v2/tools/common.jam (original)
+++ branches/release/tools/build/v2/tools/common.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -5,8 +5,8 @@
# 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)
-# Provides actions common to all toolsets, for as making directoies and
-# removing files.
+# Provides actions common to all toolsets, such as creating directories and
+# removing files.
import os ;
import modules ;
@@ -63,6 +63,7 @@
#
# Returns 'true' if the configuration has been added and an empty value if
# it already exists. Reports an error if the configuration is 'used'.
+ #
rule register ( id )
{
if $(id) in $(self.used)
@@ -88,6 +89,7 @@
# Returns 'true' if the state of the configuration has been changed to
# 'used' and an empty value if it the state wasn't changed. Reports an error
# if the configuration isn't known.
+ #
rule use ( id )
{
if ! $(id) in $(self.all)
@@ -109,24 +111,28 @@
}
# Return all registered configurations.
+ #
rule all ( )
{
return $(self.all) ;
}
# Return all used configurations.
+ #
rule used ( )
{
return $(self.used) ;
}
# Returns the value of a configuration parameter.
+ #
rule get ( id : param )
{
return $(self.$(param).$(id)) ;
}
# Sets the value of a configuration parameter.
+ #
rule set ( id : param : value * )
{
self.$(param).$(id) = $(value) ;
@@ -140,15 +146,17 @@
# will check that the combination of all parameter values is unique in all
# invocations.
#
-# Each parameter name corresponds to a subfeature. This rule will declare
-# a subfeature the first time a non-empty parameter value is passed and will
+# Each parameter name corresponds to a subfeature. This rule will declare a
+# subfeature the first time a non-empty parameter value is passed and will
# extend it with all the values.
#
# The return value from this rule is a condition to be used for flags settings.
-rule check-init-parameters ( toolset : * )
+#
+rule check-init-parameters ( toolset requirement * : * )
{
local sig = $(toolset) ;
local condition = <toolset>$(toolset) ;
+ local subcondition ;
for local index in 2 3 4 5 6 7 8 9
{
local name = $($(index)[1]) ;
@@ -185,6 +193,7 @@
.had-value.$(toolset).$(name) = true ;
}
feature.extend-subfeature toolset $(t) : $(name) : $(value) ;
+ subcondition += <toolset-$(t):$(name)>$(value) ;
}
else
{
@@ -219,11 +228,25 @@
.all-signatures += $(sig) ;
.init-loc.$(sig) = [ errors.nearest-user-location ] ;
+ # If we have a requirement, this version should only be applied under that
+ # condition. To accomplish this we add a toolset requirement that imposes
+ # the toolset subcondition, which encodes the version.
+ if $(requirement)
+ {
+ local r = <toolset>$(toolset) $(requirement) ;
+ r = $(r:J=,) ;
+ toolset.add-requirements $(r):$(subcondition) ;
+ }
+
+ # We add the requirements, if any, to the condition to scope the toolset
+ # variables and options to this specific version.
+ condition += $(requirement) ;
+
if $(.show-configuration)
{
ECHO notice: $(condition) ;
}
- return $(condition) ;
+ return $(condition:J=/) ;
}
@@ -235,6 +258,7 @@
# This rule returns the command to be used when invoking the tool. If we can't
# find the tool, a warning is issued. If 'path-last' is specified, PATH is
# checked after 'additional-paths' when searching for 'tool'.
+#
rule get-invocation-command-nodefault (
toolset : tool : user-provided-command * : additional-paths * : path-last ? )
{
@@ -265,6 +289,7 @@
# Same as get-invocation-command-nodefault, except that if no tool is found,
# returns either the user-provided-command, if present, or the 'tool' parameter.
+#
rule get-invocation-command (
toolset : tool : user-provided-command * : additional-paths * : path-last ? )
{
@@ -288,6 +313,7 @@
# Given an invocation command return the absolute path to the command. This
# works even if command has no path element and was found on the PATH.
+#
rule get-absolute-tool-path ( command )
{
if $(command:D)
@@ -304,9 +330,10 @@
# Attempts to find tool (binary) named 'name' in PATH and in 'additional-paths'.
# If found in PATH, returns 'name' and if found in additional paths, returns
-# absolute name. If the tool is found in several directories, returns all paths.
-# Otherwise, returns an empty string. If 'path-last' is specified, PATH is
-# searched after 'additional-paths'.
+# absolute name. If the tool is found in several directories, returns the
+# first path found. Otherwise, returns an empty string. If 'path-last' is
+# specified, PATH is searched after 'additional-paths'.
+#
rule find-tool ( name : additional-paths * : path-last ? )
{
local path = [ path.programs-path ] ;
@@ -342,15 +369,16 @@
# Checks if 'command' can be found either in path or is a full name to an
# existing file.
+#
rule check-tool-aux ( command )
{
if $(command:D)
{
if [ path.exists $(command) ]
# Both NT and Cygwin will run .exe files by their unqualified names.
- || [ os.on-windows ] && [ path.exists $(command).exe ]
+ || ( [ os.on-windows ] && [ path.exists $(command).exe ] )
# Only NT will run .bat files by their unqualified names.
- || [ os.name ] = NT && [ path.exists $(command).bat ]
+ || ( ( [ os.name ] = NT ) && [ path.exists $(command).bat ] )
{
return $(command) ;
}
@@ -368,6 +396,7 @@
# Checks that a tool can be invoked by 'command'. If command is not an absolute
# path, checks if it can be found in 'path'. If comand is an absolute path,
# check that it exists. Returns 'command' if ok or empty string otherwise.
+#
rule check-tool ( xcommand + )
{
if [ check-tool-aux $(xcommand[1]) ] ||
@@ -380,11 +409,13 @@
# Handle common options for toolset, specifically sets the following flag
# variables:
-# - CONFIG_COMMAND to 'command'
-# - OPTIONS for compile.c to the value of <cflags> in options
-# - OPTIONS for compile.c++ to the value of <cxxflags> in options
-# - OPTIOns for compile to the value of <compileflags> in options
-# - OPTIONs for link to the value of <linkflags> in options
+# - CONFIG_COMMAND to $(command)
+# - OPTIONS for compile to the value of <compileflags> in $(options)
+# - OPTIONS for compile.c to the value of <cflags> in $(options)
+# - OPTIONS for compile.c++ to the value of <cxxflags> in $(options)
+# - OPTIONS for compile.fortran to the value of <fflags> in $(options)
+# - OPTIONS for link to the value of <linkflags> in $(options)
+#
rule handle-options ( toolset : condition * : command * : options * )
{
if $(.debug-configuration)
@@ -392,22 +423,30 @@
ECHO "notice: will use '$(command)' for $(toolset), condition $(condition:E=(empty))" ;
}
- # The last parameter ('true') says it's OK to set flags for another module.
- toolset.flags $(toolset) CONFIG_COMMAND $(condition) : $(command) : unchecked ;
- toolset.flags $(toolset).compile OPTIONS $(condition) :
- [ feature.get-values <compileflags> : $(options) ] : unchecked ;
- toolset.flags $(toolset).compile.c OPTIONS $(condition) :
- [ feature.get-values <cflags> : $(options) ] : unchecked ;
- toolset.flags $(toolset).compile.c++ OPTIONS $(condition) :
- [ feature.get-values <cxxflags> : $(options) ] : unchecked ;
+ # The last parameter ('unchecked') says it is OK to set flags for another
+ # module.
+ toolset.flags $(toolset) CONFIG_COMMAND $(condition) : $(command)
+ : unchecked ;
+
+ toolset.flags $(toolset).compile OPTIONS $(condition) :
+ [ feature.get-values <compileflags> : $(options) ] : unchecked ;
+
+ toolset.flags $(toolset).compile.c OPTIONS $(condition) :
+ [ feature.get-values <cflags> : $(options) ] : unchecked ;
+
+ toolset.flags $(toolset).compile.c++ OPTIONS $(condition) :
+ [ feature.get-values <cxxflags> : $(options) ] : unchecked ;
+
toolset.flags $(toolset).compile.fortran OPTIONS $(condition) :
- [ feature.get-values <fflags> : $(options) ] : unchecked ;
- toolset.flags $(toolset).link OPTIONS $(condition) :
- [ feature.get-values <linkflags> : $(options) ] : unchecked ;
+ [ feature.get-values <fflags> : $(options) ] : unchecked ;
+
+ toolset.flags $(toolset).link OPTIONS $(condition) :
+ [ feature.get-values <linkflags> : $(options) ] : unchecked ;
}
-# Returns the location of the "program files" directory on a windows platform.
+# Returns the location of the "program files" directory on a Windows platform.
+#
rule get-program-files-dir ( )
{
local ProgramFiles = [ modules.peek : ProgramFiles ] ;
@@ -455,6 +494,7 @@
# visible in the environment seen by subsequently executed commands. In other
# words, on Unix systems, the variable is exported, which is consistent with the
# only possible behavior on Windows systems.
+#
rule variable-setting-command ( variable : value )
{
local nl = "
@@ -466,6 +506,34 @@
}
else
{
+ # (todo)
+ # The following does not work on CYGWIN and needs to be fixed. On
+ # CYGWIN the $(nl) variable holds a Windows new-line \r\n sequence that
+ # messes up the executed export command which then reports that the
+ # passed variable name is incorrect. This is most likely due to the
+ # extra \r character getting interpreted as a part of the variable name.
+ #
+ # Several ideas pop to mind on how to fix this:
+ # * One way would be to separate the commands using the ; shell
+ # command separator. This seems like the quickest possible
+ # solution but I do not know whether this would break code on any
+ # platforms I I have no access to.
+ # * Another would be to not use the terminating $(nl) but that would
+ # require updating all the using code so it does not simply
+ # prepend this variable to its own commands.
+ # * I guess the cleanest solution would be to update Boost Jam to
+ # allow explicitly specifying \n & \r characters in its scripts
+ # instead of always relying only on the 'current OS native newline
+ # sequence'.
+ #
+ # Some code found to depend on this behaviour:
+ # * This Boost Build module.
+ # * __test__ rule.
+ # * path-variable-setting-command rule.
+ # * python.jam toolset.
+ # * xsltproc.jam toolset.
+ # * fop.jam toolset.
+ # (todo) (07.07.2008.) (Jurko)
return "$(variable)=$(value)$(nl)export $(variable)$(nl)" ;
}
}
@@ -473,6 +541,7 @@
# Returns a command to sets a named shell path variable to the given NATIVE
# paths on the current platform.
+#
rule path-variable-setting-command ( variable : paths * )
{
local sep = [ os.path-separator ] ;
@@ -482,6 +551,7 @@
# Returns a command that prepends the given paths to the named path variable on
# the current platform.
+#
rule prepend-path-variable-command ( variable : paths * )
{
return [ path-variable-setting-command $(variable)
@@ -492,9 +562,10 @@
# Return a command which can create a file. If 'r' is result of invocation, then
# 'r foobar' will create foobar with unspecified content. What happens if file
# already exists is unspecified.
+#
rule file-creation-command ( )
{
- if [ modules.peek : NT ]
+ if [ os.name ] = NT
{
return "echo. > " ;
}
@@ -508,9 +579,10 @@
# Returns a command that may be used for 'touching' files. It is not a real
# 'touch' command on NT because it adds an empty line at the end of file but it
# works with source files.
+#
rule file-touch-command ( )
{
- if [ os.name ] in NT
+ if [ os.name ] = NT
{
return "echo. >> " ;
}
@@ -523,25 +595,33 @@
rule MkDir
{
- # If dir exists, don't update it. Do this even for $(DOT).
+ # If dir exists, do not update it. Do this even for $(DOT).
NOUPDATE $(<) ;
if $(<) != $(DOT) && ! $($(<)-mkdir)
{
# Cheesy gate to prevent multiple invocations on same dir.
- # MkDir1 has the actions.
- # Arrange for jam dirs.
-
$(<)-mkdir = true ;
- MkDir1 $(<) ;
- Depends dirs : $(<) ;
- # Recursively make parent directories.
- # $(<:P) = $(<)'s parent, & we recurse until root
+ # Schedule the mkdir build action.
+ if [ os.name ] = NT
+ {
+ MkDir1-quick-fix-for-windows $(<) ;
+ }
+ else
+ {
+ MkDir1-quick-fix-for-unix $(<) ;
+ }
- local s = $(<:P) ;
+ # Prepare a Jam 'dirs' target that can be used to make the build only
+ # construct all the target directories.
+ DEPENDS dirs : $(<) ;
+
+ # Recursively create parent directories. $(<:P) = $(<)'s parent & we
+ # recurse until root.
- if $(NT)
+ local s = $(<:P) ;
+ if [ os.name ] = NT
{
switch $(s)
{
@@ -550,14 +630,17 @@
}
}
- if $(s) && $(s) != $(<)
+ if $(s)
{
- Depends $(<) : $(s) ;
- MkDir $(s) ;
- }
- else if $(s)
- {
- NOTFILE $(s) ;
+ if $(s) != $(<)
+ {
+ DEPENDS $(<) : $(s) ;
+ MkDir $(s) ;
+ }
+ else
+ {
+ NOTFILE $(s) ;
+ }
}
}
}
@@ -569,6 +652,21 @@
}
+# (todo)
+# The following quick-fix actions should be replaced using the original MkDir1
+# action once Boost Jam gets updated to correctly detect different paths leading
+# up to the same filesystem target and triggers their build action only once.
+# (todo) (04.07.2008.) (Jurko)
+actions MkDir1-quick-fix-for-unix
+{
+ mkdir -p "$(<)"
+}
+actions MkDir1-quick-fix-for-windows
+{
+ if not exist "$(<)\\" mkdir "$(<)"
+}
+
+
actions piecemeal together existing Clean
{
$(RM) "$(>)"
@@ -628,7 +726,8 @@
# value as the version number.
# <property:/property-name/>[joiner]
# :: Direct lookup of the given property-name value in the
-# build properties.
+# build properties. /property-name/ is a regular expression.
+# e.g. <property:toolset-.*:flavor> will match every toolset.
# /otherwise/
# :: The literal value of the format argument.
#
@@ -678,10 +777,13 @@
case <property:*> :
local key = [ MATCH <property:(.*)> : $(f:G) ] ;
- local p = [ $(property-set).get [ MATCH <property:(.*)> : $(f:G) ] ] ;
- if $(p)
- {
- result += [ join-tag $(f:G=) : $(p) ] ;
+ local p0 = [ MATCH <($(key))> : [ $(property-set).raw ] ] ;
+ if $(p0) {
+ local p = [ $(property-set).get <$(p0)> ] ;
+ if $(p)
+ {
+ result += [ join-tag $(f:G=) : $(p) ] ;
+ }
}
case * :
@@ -697,7 +799,7 @@
local rule join-tag ( joiner ? : tag ? )
{
- if ! $(joinder) { joiner = - ; }
+ if ! $(joiner) { joiner = - ; }
return $(joiner)$(tag) ;
}
@@ -712,7 +814,7 @@
case borland* : tag += bcb ;
case como* : tag += como ;
case cw : tag += cw ;
- case darwin* : tag += ;
+ case darwin* : tag += xgcc ;
case edg* : tag += edg ;
case gcc* :
{
@@ -756,8 +858,8 @@
version = 7 ;
}
}
- # On intel, version is not added, because it does not matter and it's the
- # version of vc used as backend that matters. Ideally, we'd encode the
+ # On intel, version is not added, because it does not matter and it is the
+ # version of vc used as backend that matters. Ideally, we should encode the
# backend version but that would break compatibility with V1.
if $(tag) = iw
{
@@ -798,7 +900,7 @@
# toolset, the tag rules won't even see <runtime-debugging>. Similar
# functionality in V2 is not implemented yet, so we just check for toolsets
# which are known to care about runtime debug.
- if <toolset>msvc in $(properties)
+ if <toolset>msvc in $(properties)
|| <stdlib>stlport in $(properties)
|| <toolset-intel:platform>win in $(properties)
{
@@ -821,7 +923,7 @@
local nl = "
" ;
- local save-os = [ modules.peek os : name ] ;
+ local save-os = [ modules.peek os : .name ] ;
modules.poke os : .name : LINUX ;
Modified: branches/release/tools/build/v2/tools/como-linux.jam
==============================================================================
--- branches/release/tools/build/v2/tools/como-linux.jam (original)
+++ branches/release/tools/build/v2/tools/como-linux.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,9 +1,10 @@
-# Copyright 2004, 2005, 2006 Vladimir Prus
-# 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)
+# Copyright 2004, 2005, 2006 Vladimir Prus
+# 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)
# The following #// line will be used by the regression test table generation
-# program as the column heading for HTML tables. Must not include version number.
+# program as the column heading for HTML tables. Must not include a version
+# number.
#//Comeau
C++
import toolset ;
@@ -12,34 +13,36 @@
import common ;
import generators ;
-import unix ;
+import unix ;
import como ;
feature.extend-subfeature toolset como : platform : linux ;
-toolset.inherit-generators como-linux
+toolset.inherit-generators como-linux
<toolset>como <toolset-como:platform>linux : unix ;
-generators.override como-linux.prebuilt : builtin.lib-generator ;
+generators.override como-linux.prebuilt : builtin.lib-generator ;
generators.override como-linux.searched-lib-generator : searched-lib-generator ;
toolset.inherit-flags como-linux : unix ;
toolset.inherit-rules como-linux : gcc ;
-generators.register-c-compiler como-linux.compile.c++ : CPP : OBJ
- : <toolset>como <toolset-como:platform>linux ;
+generators.register-c-compiler como-linux.compile.c++ : CPP : OBJ
+ : <toolset>como <toolset-como:platform>linux ;
generators.register-c-compiler como-linux.compile.c : C : OBJ
- : <toolset>como <toolset-como:platform>linux ;
+ : <toolset>como <toolset-como:platform>linux ;
+
rule init ( version ? : command * : options * )
{
local condition = [ common.check-init-parameters como-linux
: version $(version) ] ;
-
- command = [ common.get-invocation-command como-linux : como
+
+ command = [ common.get-invocation-command como-linux : como
: $(command) ] ;
-
+
common.handle-options como-linux : $(condition) : $(command) : $(options) ;
}
+
flags como-linux C++FLAGS <exception-handling>off : --no_exceptions ;
flags como-linux C++FLAGS <exception-handling>on : --exceptions ;
@@ -98,4 +101,3 @@
{
ar rcu $(<) $(>)
}
-
Modified: branches/release/tools/build/v2/tools/como-win.jam
==============================================================================
--- branches/release/tools/build/v2/tools/como-win.jam (original)
+++ branches/release/tools/build/v2/tools/como-win.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -6,7 +6,8 @@
# http://www.boost.org/LICENSE_1_0.txt)
# The following #// line will be used by the regression test table generation
-# program as the column heading for HTML tables. Must not include version number.
+# program as the column heading for HTML tables. Must not include a version
+# number.
#//Comeau
C++
import common ;
@@ -17,38 +18,42 @@
feature.extend-subfeature toolset como : platform : win ;
-# Initializes the Comeau toolset for windows.
-# The command is the command which invokes the compiler.
-# You should either set environment variable COMO_XXX_INCLUDE where
-# XXX is the used backed (as described in documentation), or pass
-# that as part of command, e.g:
-#
+
+# Initializes the Comeau toolset for windows. The command is the command which
+# invokes the compiler. You should either set environment variable
+# COMO_XXX_INCLUDE where XXX is the used backend (as described in the
+# documentation), or pass that as part of command, e.g:
+#
# using como-win : 4.3 : "set COMO_BCC_INCLUDE=C:/include &&" como.exe ;
+#
rule init ( version ? : command * : options * )
{
local condition = [ common.check-init-parameters como-win
: version $(version) ] ;
-
+
command = [ common.get-invocation-command como-win : como.exe :
- $(command) ] ;
-
+ $(command) ] ;
+
common.handle-options como-win : $(condition) : $(command) : $(options) ;
}
-generators.register-c-compiler como-win.compile.c++ : CPP : OBJ
- : <toolset>como <toolset-como:platform>win ;
+generators.register-c-compiler como-win.compile.c++ : CPP : OBJ
+ : <toolset>como <toolset-como:platform>win ;
generators.register-c-compiler como-win.compile.c : C : OBJ
- : <toolset>como <toolset-como:platform>win ;
+ : <toolset>como <toolset-como:platform>win ;
+
+
+generators.register-linker como-win.link
+ : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
+ : EXE
+ : <toolset>como <toolset-como:platform>win ;
+
+# Note that status of shared libraries support is not clear, so we do not define
+# the link.dll generator.
+generators.register-archiver como-win.archive
+ : OBJ : STATIC_LIB
+ : <toolset>como <toolset-como:platform>win ;
-generators.register-linker como-win.link
- : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
- : EXE
- : <toolset>como <toolset-como:platform>win ;
-# Note that status of shared libraries support is not clear, so we don't
-# define the link.dll generator.
-generators.register-archiver como-win.archive
- : OBJ : STATIC_LIB
- : <toolset>como <toolset-como:platform>win ;
flags como-win C++FLAGS <exception-handling>off : --no_exceptions ;
flags como-win C++FLAGS <exception-handling>on : --exceptions ;
@@ -56,16 +61,17 @@
flags como-win CFLAGS <inlining>off : --no_inlining ;
flags como-win CFLAGS <inlining>on <inlining>full : --inlining ;
-# The following seems to be VC-specific options. At least,
-# when I uncomment then, Comeau with bcc as backend reports
-# that bcc32 invocation.
+
+# The following seems to be VC-specific options. At least, when I uncomment
+# then, Comeau with bcc as backend reports that bcc32 invocation failed.
#
#flags como-win CFLAGS <debug-symbols>on : /Zi ;
#flags como-win CFLAGS <optimization>off : /Od ;
+
flags como-win CFLAGS <cflags> ;
-flags como-win CFLAGS : -D_WIN32 ; # make sure that we get the Boost Win32 platform config header.
-flags como-win CFLAGS <threading>multi : -D_MT ; # make sure that our config knows that threading is on.
+flags como-win CFLAGS : -D_WIN32 ; # Make sure that we get the Boost Win32 platform config header.
+flags como-win CFLAGS <threading>multi : -D_MT ; # Make sure that our config knows that threading is on.
flags como-win C++FLAGS <cxxflags> ;
flags como-win DEFINES <define> ;
flags como-win UNDEFS <undef> ;
@@ -83,12 +89,12 @@
flags como-win FINDLIBS <find-shared-library> ;
flags como-win FINDLIBS <find-static-library> ;
-RM = [ common.rm-command ] ;
nl = "
" ;
-# for como, we repeat all libraries so that dependencies are always resolved
+# For como, we repeat all libraries so that dependencies are always resolved.
+#
actions link bind LIBRARIES
{
$(CONFIG_COMMAND) --no_version --no_prelink_verbose $(LINKFLAGS) -o "$(<[1]:S=)" @"@($(<[1]:W).rsp:E=$(nl)"$(>)")" "$(LIBRARIES)" "$(FINDLIBS:S=.lib)"
@@ -109,4 +115,3 @@
$(CONFIG_COMMAND) --no_version --no_prelink_verbose --prelink_object "$(>)"
lib $(ARFLAGS) /nologo /out:"$(<:S=.lib)" "$(>)"
}
-
Modified: branches/release/tools/build/v2/tools/como.jam
==============================================================================
--- branches/release/tools/build/v2/tools/como.jam (original)
+++ branches/release/tools/build/v2/tools/como.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -3,9 +3,8 @@
# (See accompanying file LICENSE_1_0.txt
# or copy at http://www.boost.org/LICENSE_1_0.txt)
-# This is a generic 'intel' toolset. Depending on the current
-# system, it forwards either to 'intel-linux' or 'intel-win'
-# modules.
+# This is a generic 'como' toolset. Depending on the current system, it
+# forwards either to 'como-linux' or 'como-win' modules.
import feature ;
import os ;
Modified: branches/release/tools/build/v2/tools/darwin.jam
==============================================================================
--- branches/release/tools/build/v2/tools/darwin.jam (original)
+++ branches/release/tools/build/v2/tools/darwin.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -3,7 +3,7 @@
# Copyright 2003, 2004, 2005, 2006 Vladimir Prus
# Copyright 2005-2007 Mat Marcus
# Copyright 2005-2007 Adobe Systems Incorporated
-# Copyright 2007 Rene Rivera
+# Copyright 2007-2008 Rene Rivera
# 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)
@@ -17,6 +17,32 @@
import generators ;
import path : basename ;
+## Use a framework.
+feature framework : : free ;
+
+## The MacOSX versions we can target.
+.macosx-versions =
+ 10.5 10.4 10.3 10.2 10.1
+ iphone-2.0 iphone-1.x iphonesim-2.0
+ ;
+
+## The MacOSX version to compile for, which maps to the SDK to use (sysroot).
+feature macosx-version
+ : $(.macosx-versions)
+ : propagated link-incompatible symmetric optional ;
+
+## The minimal MacOSX version to target.
+feature macosx-version-min
+ : $(.macosx-versions)
+ : propagated optional ;
+
+#############################################################################
+
+if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
+{
+ .debug-configuration = true ;
+}
+
feature.extend toolset : darwin ;
import gcc ;
toolset.inherit-generators darwin : gcc ;
@@ -31,6 +57,9 @@
toolset.inherit-rules darwin : gcc ;
toolset.inherit-flags darwin : gcc
: <runtime-link>static
+ <architecture>arm/<address-model>32
+ <architecture>arm/<address-model>64
+ <architecture>arm/<instruction-set>
<architecture>x86/<address-model>32
<architecture>x86/<address-model>64
<architecture>x86/<instruction-set>
@@ -38,34 +67,191 @@
<architecture>power/<address-model>64
<architecture>power/<instruction-set> ;
-# No additional initialization should be necessary
-rule init ( version ? : command * : options * )
+# Options:
+#
+# <root>PATH
+# Platform root path. The common autodetection will set this to
+# "/Developer". And when a command is given it will be set to
+# the corresponding "*.platform/Developer" directory.
+#
+rule init ( version ? : command * : options * : requirement * )
{
- local condition = [ common.check-init-parameters darwin : version $(version) ] ;
+ # - The root directory of the tool install.
+ local root = [ feature.get-values <root> : $(options) ] ;
+
+ # - The bin directory where to find the commands to execute.
+ local bin ;
+
+ # - The configured compile driver command.
local command = [ common.get-invocation-command darwin : g++ : $(command) ] ;
+ # - Autodetect the root and bin dir if not given.
+ if $(command)
+ {
+ bin ?= [ common.get-absolute-tool-path $(command[1]) ] ;
+ if $(bin) = "/usr/bin"
+ {
+ root ?= /Developer ;
+ }
+ else
+ {
+ local r = $(bin:D) ;
+ r = $(r:D) ;
+ root ?= $(r) ;
+ }
+ }
+
+ # - Autodetect the version if not given.
+ if $(command)
+ {
+ # - The 'command' variable can have multiple elements. When calling
+ # the SHELL builtin we need a single string.
+ local command-string = $(command:J=" ") ;
+ version ?= [ MATCH "^([0-9.]+)"
+ : [ SHELL "$(command-string) -dumpversion" ] ] ;
+ }
+
+ # - Define the condition for this toolset instance.
+ local condition =
+ [ common.check-init-parameters darwin $(requirement) : version $(version) ] ;
+
+ # - Set the toolset generic common options.
common.handle-options darwin : $(condition) : $(command) : $(options) ;
- # GCC 4.0 and higher in Darwin does not have -fcoalesce-templates.
- local gccversion = [ SHELL "$(command) -dumpversion" ] ;
- if $(gccversion) < "4.0.0"
+ # - GCC 4.0 and higher in Darwin does not have -fcoalesce-templates.
+ if $(version) < "4.0.0"
{
flags darwin.compile.c++ OPTIONS $(condition) : -fcoalesce-templates ;
}
+ # - GCC 4.2 and higher in Darwin does not have -Wno-long-double.
+ if $(version) < "4.2.0"
+ {
+ flags darwin.compile OPTIONS $(condition) : -Wno-long-double ;
+ }
+ # - Set the link flags common with the GCC toolset.
gcc.init-link-flags darwin darwin $(condition) ;
+
+ # - The symbol strip program.
+ local strip ;
+ if <striper> in $(options)
+ {
+ # We can turn off strip by specifying it as empty. In which
+ # case we switch to using the linker to do the strip.
+ flags darwin.link.dll OPTIONS
+ $(condition)/<main-target-type>LIB/<link>shared/<address-model>32/<debug-symbols>off : -Wl,-x ;
+ flags darwin.link.dll OPTIONS
+ $(condition)/<main-target-type>LIB/<link>shared/<address-model>/<debug-symbols>off : -Wl,-x ;
+ flags darwin.link OPTIONS
+ $(condition)/<main-target-type>EXE/<address-model>32/<debug-symbols>off : -s ;
+ flags darwin.link OPTIONS
+ $(condition)/<main-target-type>EXE/<address-model>/<debug-symbols>off : -s ;
+ }
+ else
+ {
+ # Otherwise we need to find a strip program to use. And hence
+ # also tell the link action that we need to use a strip
+ # post-process.
+ flags darwin.link NEED_STRIP $(condition)/<debug-symbols>off : "" ;
+ strip =
+ [ common.get-invocation-command darwin
+ : strip : [ feature.get-values <striper> : $(options) ] : $(bin) : search-path ] ;
+ flags darwin.link .STRIP $(condition) : $(strip[1]) ;
+ if $(.debug-configuration)
+ {
+ ECHO notice: using strip :: $(condition) :: $(strip[1]) ;
+ }
+ }
+
+ # - The archive builder (libtool is the default as creating
+ # archives in darwin is complicated.
+ local archiver =
+ [ common.get-invocation-command darwin
+ : libtool : [ feature.get-values <archiver> : $(options) ] : $(bin) : search-path ] ;
+ flags darwin.archive .LIBTOOL $(condition) : $(archiver[1]) ;
+ if $(.debug-configuration)
+ {
+ ECHO notice: using archiver :: $(condition) :: $(archiver[1]) ;
+ }
+
+ # - Initialize the SDKs available in the root for this tool.
+ local sdks = [ init-available-sdk-versions $(condition) : $(root) ] ;
- flags darwin.link NEED_STRIP $(condition)/<debug-symbols>off : "" ;
+ #~ ECHO --- ;
+ #~ ECHO --- bin :: $(bin) ;
+ #~ ECHO --- root :: $(root) ;
+ #~ ECHO --- version :: $(version) ;
+ #~ ECHO --- condition :: $(condition) ;
+ #~ ECHO --- strip :: $(strip) ;
+ #~ ECHO --- archiver :: $(archiver) ;
+ #~ ECHO --- sdks :: $(sdks) ;
+ #~ ECHO --- ;
+ #~ EXIT ;
}
-feature framework : : free ;
+# Determine the MacOSX SDK versions installed and their locations.
+local rule init-available-sdk-versions ( condition * : root ? )
+{
+ root ?= /Developer ;
+ local sdks-root = $(root)/SDKs ;
+ local sdks = [ GLOB $(sdks-root) : MacOSX*.sdk iPhoneOS*.sdk iPhoneSimulator*.sdk ] ;
+ local result ;
+ for local sdk in $(sdks)
+ {
+ local sdk-match = [ MATCH ([^0-9]+)([0-9]+)[.]([0-9x]+)[.]?([0-9x]+)? : $(sdk:D=) ] ;
+ local sdk-platform = $(sdk-match[1]:L) ;
+ local sdk-version = $(sdk-match[2]).$(sdk-match[3]) ;
+ if $(sdk-version)
+ {
+ switch $(sdk-platform)
+ {
+ case macosx :
+ {
+ sdk-version = $(sdk-version) ;
+ }
+ case iphoneos :
+ {
+ sdk-version = iphone-$(sdk-version) ;
+ }
+ case iphonesimulator :
+ {
+ sdk-version = iphonesim-$(sdk-version) ;
+ }
+ case * :
+ {
+ sdk-version = $(sdk-version:J=-) ;
+ }
+ }
+ result += $(sdk-version) ;
+ flags darwin.compile OPTIONS $(condition)/<macosx-version>$(sdk-version)
+ : -isysroot $(sdk) ;
+ flags darwin.link OPTIONS $(condition)/<macosx-version>$(sdk-version)
+ : -isysroot $(sdk) ;
+ if $(.debug-configuration)
+ {
+ ECHO notice: available sdk :: $(condition)/<macosx-version>$(sdk-version) :: $(sdk) ;
+ }
+ }
+ }
+ return $(result) ;
+}
+
+# Generic options.
+flags darwin.compile OPTIONS <flags> ;
+
+# Minimal OSX target option. Note that the default is for the min-version
+# option to not be included to let the compiler default take hold.
+for local macosx-version in $(.macosx-versions)
+{
+ flags darwin.compile OPTIONS <macosx-version-min>$(macosx-version)
+ : -mmacosx-version-min=$(macosx-version) ;
+ flags darwin.link OPTIONS <macosx-version-min>$(macosx-version)
+ : -mmacosx-version-min=$(macosx-version) ;
+}
# The following adds objective-c support to darwin.
# Thanks to http://thread.gmane.org/gmane.comp.lib.boost.build/13759
-type.register OBJECTIVE_C : m ;
-type.register OBJECTIVE_CPP : mm ;
-
generators.register-c-compiler darwin.compile.m : OBJECTIVE_C : OBJ : <toolset>darwin ;
generators.register-c-compiler darwin.compile.mm : OBJECTIVE_CPP : OBJ : <toolset>darwin ;
@@ -89,46 +275,6 @@
"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
}
-# Determine the MacOSX SDK versions installed and their locations.
-local rule available-macosx-versions ( )
-{
- local sdks = [ GLOB /Developer/SDKs : MacOSX* ] ;
- for local sdk in $(sdks)
- {
- local sdk-version = [ MATCH ([0-9]+)[.]([0-9]+)[.]?([0-9]+)? : $(sdk:D=) ] ;
- sdk-version = $(sdk-version:J=.) ;
- if $(sdk-version)
- {
- .macosx-sdk = $(sdk-version) $(.macosx-sdk) ;
- .macosx-sdk.$(sdk-version) = $(sdk) ;
- }
- }
- return $(.macosx-sdk) ;
-}
-
-# Add the found SDK version only to the allowed set. The "latests" SDKs
-# wil be first in the list, and hence the default.
-feature macosx-version
- : [ available-macosx-versions ]
- : propagated link-incompatible symmetric ;
-if 10.4 in [ feature.values macosx-version ]
-{
- feature.set-default macosx-version : 10.4 ;
-}
-
-# Add the options for all the found SDKs.
-for local sdk in $(.macosx-sdk)
-{
- flags darwin.compile OPTIONS <macosx-version>$(sdk) :
- -isysroot $(.macosx-sdk.$(sdk))
- -mmacosx-version-min=$(sdk)
- ;
- flags darwin.link OPTIONS <macosx-version>$(sdk) :
- -isysroot $(.macosx-sdk.$(sdk))
- -mmacosx-version-min=$(sdk)
- ;
-}
-
# Add option selection for combined and specific architecture combinations.
local rule arch-addr-flags ( toolset variable
@@ -155,20 +301,31 @@
arch-addr-flags darwin OPTIONS : power : 32 : -arch ppc : default ;
arch-addr-flags darwin OPTIONS : power : 64 : -arch ppc64 ;
+arch-addr-flags darwin OPTIONS : arm : 32 : -arch arm : default ;
+# Set the max header padding to allow renaming of libs for installation.
+flags darwin.link.dll OPTIONS : -headerpad_max_install_names ;
+
+# To link the static runtime we need to link to all the core runtime libraries.
flags darwin.link OPTIONS <runtime-link>static
: -nodefaultlibs -shared-libgcc -lstdc++-static -lgcc_eh -lgcc -lSystem ;
-flags darwin.link OPTIONS <variant>release : -Wl,-dead_strip -no_dead_strip_inits_and_terms ;
+# Strip as much as possible when optimizing.
+flags darwin.link OPTIONS <optimization>speed : -Wl,-dead_strip -no_dead_strip_inits_and_terms ;
+flags darwin.link OPTIONS <optimization>space : -Wl,-dead_strip -no_dead_strip_inits_and_terms ;
+# Dynamic/shared linking.
flags darwin.compile OPTIONS <link>shared : -dynamic ;
-flags darwin.compile OPTIONS : -Wno-long-double -no-cpp-precomp -gdwarf-2 ;
+# Misc options.
+flags darwin.compile OPTIONS : -no-cpp-precomp -gdwarf-2 ;
+
+# Add the framework names to use.
flags darwin.link FRAMEWORK <framework> ;
# This is flag is useful for debugging the link step
# uncomment to see what libtool is doing under the hood
-# flags darwin.link.dll OPTIONS : -Wl,-v ;
+#~ flags darwin.link.dll OPTIONS : -Wl,-v ;
_ = " " ;
@@ -195,8 +352,8 @@
actions link bind LIBRARIES
{
- $(CONFIG_COMMAND) -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS)
- $(NEED_STRIP)strip $(NEED_STRIP)"$(<)"
+ "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS)
+ $(NEED_STRIP)"$(.STRIP)" $(NEED_STRIP)"$(<)"
}
rule link.dll
@@ -206,12 +363,12 @@
actions link.dll bind LIBRARIES
{
- $(CONFIG_COMMAND) -dynamiclib -install_name "$(<:B)$(<:S)" -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS)
+ "$(CONFIG_COMMAND)" -dynamiclib -Wl,-single_module -install_name "$(<:B)$(<:S)" -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS)
}
# We use libtool instead of ar to support universal binary linking
# TODO: Find a way to use the underlying tools, i.e. lipo, to do this.
actions piecemeal archive
{
- libtool -static -o "$(<:T)" $(ARFLAGS) "$(>:T)"
+ "$(.LIBTOOL)" -static -o "$(<:T)" $(ARFLAGS) "$(>:T)"
}
Modified: branches/release/tools/build/v2/tools/doxygen.jam
==============================================================================
--- branches/release/tools/build/v2/tools/doxygen.jam (original)
+++ branches/release/tools/build/v2/tools/doxygen.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -4,19 +4,18 @@
# 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)
-# This module defines rules to handle generation of various outputs
-# from source files documented with doxygen comments. The supported
-# transformations are:
+# This module defines rules to handle generation of various outputs from source
+# files documented with doxygen comments. The supported transformations are:
#
# * Source -> Doxygen XML -> BoostBook XML
# * Source -> Doxygen HTML
#
-# The type of transformation is selected based on the target requested.
-# For BoostBook XML, the default, specifying a target with an ".xml" suffix,
-# or an empty suffix, will produce a <target>.xml and <target>.boostbook.
-# For Doxygen HTML specifying a target with an ".html" suffix will produce
-# a directory <target> with the Doxygen html files, and a <target>.html file
-# redirecting to that directory.
+# The type of transformation is selected based on the target requested. For
+# BoostBook XML, the default, specifying a target with an ".xml" suffix, or an
+# empty suffix, will produce a <target>.xml and <target>.boostbook. For Doxygen
+# HTML specifying a target with an ".html" suffix will produce a directory
+# <target> with the Doxygen html files, and a <target>.html file redirecting to
+# that directory.
import "class" : new ;
import targets ;
@@ -38,6 +37,7 @@
import common ;
import modules ;
+
# Use to specify extra configuration paramters. These get translated
# into a doxyfile which configures the building of the docs.
feature.feature doxygen:param : : free ;
@@ -75,9 +75,11 @@
# Redirection HTML file to HTML multifile directory.
type.register DOXYGEN_HTML : : HTML ;
+
# Initialize the Doxygen module. Parameters are:
# name: the name of the 'doxygen' executable. If not specified, the name
# 'doxygen' will be used
+#
rule init ( name ? )
{
if ! $(.initialized)
@@ -86,6 +88,8 @@
if ! $(name)
{
+ local doxygen-path ;
+
if [ os.name ] = NT
{
local ProgramFiles = [ modules.peek : ProgramFiles ] ;
@@ -97,51 +101,40 @@
{
ProgramFiles = "C:\\Program Files" ;
}
-
- local doxygen-path =
+
+ doxygen-path =
[ GLOB
[ modules.peek : PATH ]
"$(ProgramFiles)\\doxygen\\bin"
: doxygen\.exe ] ;
- doxygen-path = $(doxygen-path[1]) ;
-
- if $(doxygen-path)
- {
- if --debug-configuration in [ modules.peek : ARGV ]
- {
- ECHO "notice:" using doxygen ":" $(doxygen-path) ;
- }
- .doxygen = $(doxygen-path) ;
- }
}
else
{
- local doxygen-path =
+ doxygen-path =
[ GLOB
[ modules.peek : PATH ]
: doxygen ] ;
- doxygen-path = $(doxygen-path[1]) ;
-
- if $(doxygen-path)
- {
- if --debug-configuration in [ modules.peek : ARGV ]
- {
- ECHO "notice:" using doxygen ":" $(doxygen-path) ;
- }
- .doxygen = $(doxygen-path) ;
- }
}
+
+ doxygen-path = $(doxygen-path[1]) ;
+
+ if $(doxygen-path)
+ {
+ .doxygen = $(doxygen-path) ;
+ }
+
+ .doxygen ?= doxygen ;
}
else
{
- if --debug-configuration in [ modules.peek : ARGV ]
- {
- ECHO "notice:" using doxygen ":" $(name) ;
- }
.doxygen = $(name) ;
}
- .doxygen ?= doxygen ;
-
+
+ if --debug-configuration in [ modules.peek : ARGV ]
+ {
+ ECHO "notice:" using doxygen ":" $(.doxygen) ;
+ }
+
.doxproc = [ modules.binding $(__name__) ] ;
.doxproc = $(.doxproc:D)/doxproc.py ;
@@ -164,35 +157,41 @@
}
}
+
rule name ( )
{
return $(.doxygen) ;
}
-# Runs Doxygen on the given Doxygen configuration file (the source) to
-# generate the Doxygen files. The output is dumped according to the settings
-# in the Doxygen configuration file, not according to the target! Because
-# of this, we essentially "touch" the target file, in effect making it look
-# like we've really written something useful to it. Anyone that uses this
-# action must deal with this behavior.
+
+# Runs Doxygen on the given Doxygen configuration file (the source) to generate
+# the Doxygen files. The output is dumped according to the settings in the
+# Doxygen configuration file, not according to the target! Because of this, we
+# essentially "touch" the target file, in effect making it look like we have
+# really written something useful to it. Anyone that uses this action must deal
+# with this behavior.
+#
actions doxygen-action
{
- $(RM) "$(*.XML)" & "$(NAME:E=doxygen)" $(>) && echo "Stamped" > "$(<)"
+ $(RM) "$(*.XML)" & "$(NAME:E=doxygen)" "$(>)" && echo "Stamped" > "$(<)"
}
+
# Runs the Python doxproc XML processor.
+#
actions doxproc
{
python "$(DOXPROC)" "--xmldir=$(>)" "--output=$(<)" "$(OPTIONS)" "--id=$(ID)" "--title=$(TITLE)"
}
-# Generates a doxygen configuration file (doxyfile) given a set of C++
-# sources and a property list that may contain <doxygen:param>
-# features.
+
+# Generates a doxygen configuration file (doxyfile) given a set of C++ sources
+# and a property list that may contain <doxygen:param> features.
+#
rule headers-to-doxyfile ( target : sources * : properties * )
{
local text "# Generated by Boost.Build version 2" ;
-
+
local output-dir ;
# Translate <doxygen:param> into command line flags.
@@ -205,30 +204,27 @@
output-dir = "$(namevalue[2])" ;
}
}
-
+
if ! $(output-dir)
{
output-dir = [ on $(target) return $(LOCATE) ] ;
- text += "OUTPUT_DIRECTORY = $(output-dir)" ;
+ text += "OUTPUT_DIRECTORY = \"$(output-dir)\"" ;
}
- local headers = "" ;
- for local source in $(sources:G=)
- {
- headers = "$(headers) $(source)" ;
- }
+ local headers = \"$(sources:G=)\" ;
- # Doxygen generates LaTex by default. So disable it unconditionally,
- # or at least until someone needs, and hence writes support for, LaTex
- # output.
+ # Doxygen generates LaTex by default. So disable it unconditionally, or at
+ # least until someone needs, and hence writes support for, LaTex output.
text += "GENERATE_LATEX = NO" ;
- text += "INPUT = $(headers) " ;
+ text += "INPUT = $(headers:J= )" ;
print.output $(target) plain ;
print.text $(text) : true ;
}
-# Run Doxygen. See doxygen-action for a description of the strange
-# properties of this rule
+
+# Run Doxygen. See doxygen-action for a description of the strange properties of
+# this rule.
+#
rule run ( target : source : properties * )
{
doxygen-action $(target) : $(source) ;
@@ -239,14 +235,13 @@
[ path.join
[ path.make [ on $(target) return $(LOCATE) ] ]
$(target:B:S=)
- *.xml ]
- ]
- ;
+ *.xml ] ] ;
}
-# The rules below require Boost.Book stylesheets, so we need
-# some code to check that the boostbook module is actaully
-# initialized.
+
+# The rules below require Boost.Book stylesheets, so we need some code to check
+# that the boostbook module has actualy been initialized.
+#
rule check-boostbook ( )
{
if ! [ modules.peek boostbook : .initialized ]
@@ -259,37 +254,39 @@
}
}
-# Collect the set of Doxygen XML files into a single XML source file
-# that can be handled by an XSLT processor. The source is completely
-# ignored (see doxygen-action), because this action picks up the
-# Doxygen XML index file xml/index.xml. This is because we can't teach
-# Doxygen to act like a NORMAL program and take a "-o output.xml"
-# argument (grrrr). The target of the collection will be a single
-# Doxygen XML file.
+
+# Collect the set of Doxygen XML files into a single XML source file that can be
+# handled by an XSLT processor. The source is completely ignored (see
+# doxygen-action), because this action picks up the Doxygen XML index file
+# xml/index.xml. This is because we can not teach Doxygen to act like a NORMAL
+# program and take a "-o output.xml" argument (grrrr). The target of the
+# collection will be a single Doxygen XML file.
+#
rule collect ( target : source : properties * )
{
check-boostbook ;
- local collect-xsl-dir = [ path.native
- [ path.join [ boostbook.xsl-dir ] doxygen collect ]
- ] ;
+ local collect-xsl-dir
+ = [ path.native [ path.join [ boostbook.xsl-dir ] doxygen collect ] ] ;
local source-path
= [ path.make [ on $(source) return $(LOCATE) ] ] ;
local collect-path
- = [ path.join [ path.pwd ] $(source-path) $(source:B) ] ;
+ = [ path.root [ path.join $(source-path) $(source:B) ] [ path.pwd ] ] ;
+ local native-path
+ = [ path.native $(collect-path) ] ;
local real-source
- = [ path.native [ path.join [ path.native $(collect-path) ] index.xml ] ] ;
+ = [ path.native [ path.join $(collect-path) index.xml ] ] ;
xsltproc.xslt $(target) : $(real-source) $(collect-xsl-dir:S=.xsl)
- : <xsl:param>doxygen.xml.path=$(collect-path)
- ;
+ : <xsl:param>doxygen.xml.path=$(native-path) ;
}
-# Translate Doxygen XML into BoostBook
+
+# Translate Doxygen XML into BoostBook.
+#
rule xml-to-boostbook ( target : source : properties * )
{
check-boostbook ;
local xsl-dir = [ boostbook.xsl-dir ] ;
- local d2b-xsl = [ path.native
- [ path.join [ boostbook.xsl-dir ] doxygen
+ local d2b-xsl = [ path.native [ path.join [ boostbook.xsl-dir ] doxygen
doxygen2boostbook.xsl ] ] ;
local xslt-properties = $(properties) ;
@@ -305,20 +302,24 @@
xsltproc.xslt $(target) : $(source) $(d2b-xsl) : $(xslt-properties) ;
}
+
flags doxygen.xml-dir-to-boostbook OPTIONS <doxygen.doxproc.index>yes : --enable-index ;
flags doxygen.xml-dir-to-boostbook ID <doxygen.doxproc.id> ;
flags doxygen.xml-dir-to-boostbook TITLE <doxygen.doxproc.title> ;
+
rule xml-dir-to-boostbook ( target : source : properties * )
{
DOXPROC on $(target) = $(.doxproc) ;
-
+
LOCATE on $(source:S=) = [ on $(source) return $(LOCATE) ] ;
-
+
doxygen.doxproc $(target) : $(source:S=) ;
}
+
# Generate the HTML redirect to HTML dir index.html file.
+#
rule html-redirect ( target : source : properties * )
{
local uri = "$(target:B)/index.html" ;
@@ -342,7 +343,9 @@
: true ;
}
+
# User-level rule to generate BoostBook XML from a set of headers via Doxygen.
+#
rule doxygen ( target : sources * : requirements * : default-build * : usage-requirements * )
{
local project = [ project.current ] ;
@@ -353,11 +356,10 @@
local html-location = [ feature.get-values <location> : $(requirements) ] ;
local output-dir = [ path.root
[ path.join [ $(project).get build-dir ] $(html-location:E=html) ]
- [ path.pwd ]
- ] ;
+ [ path.pwd ] ] ;
local output-dir-native = [ path.native $(output-dir) ] ;
requirements = [ property.change $(requirements) : <location> ] ;
-
+
## The doxygen configuration file.
targets.main-target-alternative
[ new typed-target $(target:S=.tag) : $(project) : DOXYFILE
@@ -365,13 +367,13 @@
: [ targets.main-target-requirements $(requirements)
<doxygen:param>GENERATE_HTML=YES
<doxygen:param>GENERATE_XML=NO
- <doxygen:param>"OUTPUT_DIRECTORY=$(output-dir-native)"
+ <doxygen:param>"OUTPUT_DIRECTORY=\"$(output-dir-native)\""
<doxygen:param>HTML_OUTPUT=$(target:B)
: $(project) ]
: [ targets.main-target-default-build $(default-build) : $(project) ]
] ;
$(project).mark-target-as-explicit $(target:S=.tag) ;
-
+
## The html directory to generate by running doxygen.
targets.main-target-alternative
[ new typed-target $(target:S=.dir) : $(project) : DOXYGEN_HTML_MULTIFILE
@@ -381,7 +383,7 @@
: [ targets.main-target-default-build $(default-build) : $(project) ]
] ;
$(project).mark-target-as-explicit $(target:S=.dir) ;
-
+
## The redirect html file into the generated html.
targets.main-target-alternative
[ new typed-target $(target) : $(project) : DOXYGEN_HTML
@@ -398,7 +400,7 @@
local location-xml = [ feature.get-values <location> : $(requirements) ] ;
requirements = [ property.change $(requirements) : <location> ] ;
local target-xml = $(target:B=$(target:B)-xml) ;
-
+
## The doxygen configuration file.
targets.main-target-alternative
[ new typed-target $(target-xml:S=.tag) : $(project) : DOXYFILE
@@ -411,7 +413,7 @@
: [ targets.main-target-default-build $(default-build) : $(project) ]
] ;
$(project).mark-target-as-explicit $(target-xml:S=.tag) ;
-
+
## The Doxygen XML directory of the processed source files.
targets.main-target-alternative
[ new typed-target $(target-xml:S=.dir) : $(project) : DOXYGEN_XML_MULTIFILE
@@ -421,7 +423,7 @@
: [ targets.main-target-default-build $(default-build) : $(project) ]
] ;
$(project).mark-target-as-explicit $(target-xml:S=.dir) ;
-
+
## The resulting BoostBook file is generated by the processor tool. The
## tool can be either the xsltproc plus accompanying XSL scripts. Or it
## can be the python doxproc.py script.
@@ -444,10 +446,10 @@
: [ targets.main-target-default-build $(default-build) : $(project) ]
] ;
$(project).mark-target-as-explicit $(target:S=.xml) ;
-
+
targets.main-target-alternative
[ new alias-target-class $(target) : $(project)
- :
+ :
: [ targets.main-target-requirements $(requirements)
: $(project) ]
: [ targets.main-target-default-build $(default-build) : $(project) ]
Modified: branches/release/tools/build/v2/tools/gcc.jam
==============================================================================
--- branches/release/tools/build/v2/tools/gcc.jam (original)
+++ branches/release/tools/build/v2/tools/gcc.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -141,6 +141,10 @@
{
linker = hpux ;
}
+ else if [ os.name ] = AIX
+ {
+ linker = aix ;
+ }
else
{
linker = gnu ;
@@ -327,7 +331,7 @@
# implement and will increase target path length even more.
flags gcc.compile OPTIONS <link>shared : -fPIC ;
}
-if [ os.name ] != NT && [ os.name ] != OSF && [ os.name ] != HPUX
+if [ os.name ] != NT && [ os.name ] != OSF && [ os.name ] != HPUX && [ os.name ] != AIX
{
# OSF does have an option called -soname but it doesn't seem to work as
# expected, therefore it has been disabled.
@@ -611,6 +615,33 @@
flags $(toolset).link OPTIONS $(condition)/<link>shared
: -fPIC : unchecked ;
}
+
+ case aix :
+ {
+ #
+ # On AIX we *have* to use the native linker.
+ #
+ # Using -brtl, the AIX linker will look for libraries with both the .a and .so
+ # extensions, such as libfoo.a and libfoo.so. Without -brtl, the AIX linker
+ # looks only for libfoo.a. Note that libfoo.a is an archived file that may
+ # contain shared objects and is different from static libs as on Linux.
+ #
+ # The -bnoipath strips the prepending (relative) path of libraries from
+ # the loader section in the target library or executable. Hence, during load-
+ # time LIBPATH (identical to LD_LIBRARY_PATH) or a hard-coded -blibpath
+ # (*similar* to -lrpath/-lrpath-link) is searched. Without this option,
+ # the prepending (relative) path + library name is hard-coded in the loader
+ # section, causing *only* this path to be searched during load-time.
+ # Note that the AIX linker does not have an -soname equivalent, this
+ # is as close as it gets.
+ #
+ # The above options are definately for AIX 5.x, and most likely also for
+ # AIX 4.x and AIX 6.x. For details about AIX linker:
+ # http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf
+ #
+
+ flags $(toolset).link OPTIONS : -Wl,-brtl -Wl,-bnoipath : unchecked ;
+ }
case * :
{
@@ -712,7 +743,7 @@
case SunOS* :
{
flags gcc OPTIONS <threading>multi : -pthreads ;
- flags gcc FINDLIBS-SA <threading>multi : rt ;
+ flags gcc FINDLIBS-SA : rt ;
}
case BeOS :
{
@@ -740,7 +771,7 @@
case * :
{
flags gcc OPTIONS <threading>multi : -pthread ;
- flags gcc FINDLIBS-SA <threading>multi : rt ;
+ flags gcc FINDLIBS-SA : rt ;
}
}
}
@@ -817,7 +848,6 @@
# RS/6000 & PowerPC
flags gcc OPTIONS <architecture>power/<address-model>32 : -m32 ;
flags gcc OPTIONS <architecture>power/<address-model>64 : -m64 ;
-flags gcc OPTIONS <architecture>power/<address-model>/<instruction-set> : -mcpu=common ;
cpu-flags gcc OPTIONS : power : 403 : -mcpu=403 ;
cpu-flags gcc OPTIONS : power : 505 : -mcpu=505 ;
cpu-flags gcc OPTIONS : power : 601 : -mcpu=601 ;
Modified: branches/release/tools/build/v2/tools/intel-darwin.jam
==============================================================================
--- branches/release/tools/build/v2/tools/intel-darwin.jam (original)
+++ branches/release/tools/build/v2/tools/intel-darwin.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -105,6 +105,13 @@
flags intel-darwin.link OPTIONS $(condition)/<runtime-link>static : -static -static-intel -lstdc++ -lpthread ;
flags intel-darwin.link OPTIONS $(condition)/<runtime-link>shared : -shared-intel -lstdc++ -lpthread ;
}
+
+ local minor = [ MATCH ".*\\.(.).*" : $(version) ] ;
+
+ # wchar_t char_traits workaround for compilers older than 10.2
+ if $(major) = "9" || ( $(major) = "10" && ( $(minor) = "0" || $(minor) = "1" ) ) {
+ flags intel-darwin.compile DEFINES $(condition) : __WINT_TYPE__=int : unchecked ;
+ }
}
SPACE = " " ;
@@ -117,8 +124,8 @@
#
cpu-type-em64t = prescott nocona ;
-# flags intel-darwin.compile OPTIONS <instruction-set>$(cpu-type-em64t)/<address-model>32 : -mcmodel=small ;
-flags intel-darwin.compile OPTIONS <instruction-set>$(cpu-type-em64t)/<address-model>64 : -mcmodel=large ;
+flags intel-darwin.compile OPTIONS <instruction-set>$(cpu-type-em64t)/<address-model>32 : -m32 ; # -mcmodel=small ;
+flags intel-darwin.compile OPTIONS <instruction-set>$(cpu-type-em64t)/<address-model>64 : -m64 ; # -mcmodel=large ;
flags intel-darwin.compile.c OPTIONS <warnings>off : -w0 ;
flags intel-darwin.compile.c OPTIONS <warnings>on : -w1 ;
Modified: branches/release/tools/build/v2/tools/intel-win.jam
==============================================================================
--- branches/release/tools/build/v2/tools/intel-win.jam (original)
+++ branches/release/tools/build/v2/tools/intel-win.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -73,6 +73,9 @@
local major = $(m[1]) ;
local C++FLAGS ;
+
+ C++FLAGS += /nologo ;
+
# Reduce the number of spurious error messages
C++FLAGS += /Qwn5 /Qwd985 ;
Modified: branches/release/tools/build/v2/tools/make.jam
==============================================================================
--- branches/release/tools/build/v2/tools/make.jam (original)
+++ branches/release/tools/build/v2/tools/make.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,9 +1,9 @@
-# Copyright 2003 Dave Abrahams
-# Copyright 2003 Douglas Gregor
-# Copyright 2006 Rene Rivera
-# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
-# 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)
+# Copyright 2003 Dave Abrahams
+# Copyright 2003 Douglas Gregor
+# Copyright 2006 Rene Rivera
+# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
+# 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)
# This module defines the 'make' main target rule.
@@ -16,58 +16,56 @@
import property-set ;
import project ;
+
class make-target-class : basic-target
{
- import type regex virtual-target ;
+ import type regex virtual-target ;
import "class" : new ;
-
+
rule __init__ ( name : project : sources * : requirements *
: default-build * : usage-requirements * )
- {
- basic-target.__init__ $(name) : $(project) : $(sources)
+ {
+ basic-target.__init__ $(name) : $(project) : $(sources)
: $(requirements) : $(default-build) : $(usage-requirements) ;
}
-
+
rule construct ( name : source-targets * : property-set )
{
- local action-name = [ $(property-set).get <action> ] ;
- # 'm' will always be set -- we add '@' outselfs in 'make'
- # rule below.
+ local action-name = [ $(property-set).get <action> ] ;
+ # 'm' will always be set -- we add '@' ourselves in 'make' rule below.
local m = [ MATCH ^@(.*) : $(action-name) ] ;
-
- local a = [ new action $(source-targets) : $(m[1])
- : $(property-set) ] ;
- local t = [ new file-target $(self.name) exact
- : [ type.type $(self.name) ] : $(self.project) : $(a) ] ;
+
+ local a = [ new action $(source-targets) : $(m[1]) : $(property-set) ] ;
+ local t = [ new file-target $(self.name) exact
+ : [ type.type $(self.name) ] : $(self.project) : $(a) ] ;
return [ property-set.empty ] [ virtual-target.register $(t) ] ;
- }
+ }
}
+
# Declares the 'make' main target.
+#
rule make ( target-name : sources * : generating-rule + : requirements *
: usage-requirements * )
{
local project = [ project.current ] ;
-
- # The '@' sign causes the feature.jam module to qualify rule name
- # with the module name of current project, if needed.
+
+ # The '@' sign causes the feature.jam module to qualify rule name with the
+ # module name of current project, if needed.
local m = [ MATCH ^(@).* : $(generating-rule) ] ;
if ! $(m)
{
generating-rule = @$(generating-rule) ;
- }
+ }
requirements += <action>$(generating-rule) ;
-
+
targets.main-target-alternative
- [ new make-target-class $(target-name) : $(project)
- : [ targets.main-target-sources $(sources) : $(target-name) ]
- : [ targets.main-target-requirements $(requirements) : $(project) ]
- : [ targets.main-target-default-build : $(project) ]
- : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
+ [ new make-target-class $(target-name) : $(project)
+ : [ targets.main-target-sources $(sources) : $(target-name) ]
+ : [ targets.main-target-requirements $(requirements) : $(project) ]
+ : [ targets.main-target-default-build : $(project) ]
+ : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
] ;
-
}
IMPORT $(__name__) : make : : make ;
-
-
Modified: branches/release/tools/build/v2/tools/msvc.jam
==============================================================================
--- branches/release/tools/build/v2/tools/msvc.jam (original)
+++ branches/release/tools/build/v2/tools/msvc.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -86,25 +86,55 @@
# "x.y" - refers to a detected version;
# "a.b" - refers to an undetected version.
#
-# Note: for free VC7.1 tools, we don't correctly find vcvars32.bar when user
+# Note: for free VC7.1 tools, we do not correctly find vcvars32.bar when user
# explicitly provides a path.
+#
rule init (
- version ? # the msvc version which is being configured. When omitted
- # the tools invoked when no explicit version is given will be configured.
+ # The msvc version being configured. When omitted the tools invoked when no
+ # explicit version is given will be configured.
+ version ?
+
+ # The command used to invoke the compiler. If not specified:
+ # - if version is given, default location for that version will be
+ # searched
+ #
+ # - if version is not given, default locations for MSVC 9.0, 8.0, 7.1, 7.0
+ # and 6.* will be searched
+ #
+ # - if compiler is not found in the default locations, PATH will be
+ # searched.
: command *
- # the command to invoke the compiler. If not specified:
- # - if version is given, default location for that version will be searched
+
+ # Options may include:
#
- # - if version is not given, default locations for 7.1, 7.0 and 6.* will
- # be searched
+ # All options shared by multiple toolset types as handled by the
+ # common.handle-options() rule, e.g. <cflags>, <compileflags>, <cxxflags>,
+ # <fflags> & <linkflags>.
#
- # - if compiler is not found in default locations, PATH will be searched.
- : options *
- # options can include <setup>, <compiler>, <assembler>, <linker> and <resource-compiler>
+ # <assembler>
+ # <compiler>
+ # <idl-compiler>
+ # <linker>
+ # <mc-compiler>
+ # <resource-compiler>
+ # Exact tool names to be used by this msvc toolset configuration.
#
# <compiler-filter>
- # Command to pipe the output of running the compiler. For example
- # to pass the output to STLfilt.
+ # Command through which to pipe the output of running the compiler.
+ # For example to pass the output to STLfilt.
+ #
+ # <setup>
+ # Global setup command to invoke before running any of the msvc tools.
+ # It will be passed additional option parameters depending on the actual
+ # target platform.
+ #
+ # <setup-amd64>
+ # <setup-i386>
+ # <setup-ia64>
+ # Platform specific setup command to invoke before running any of the
+ # msvc tools used when builing a target for a specific platform, e.g.
+ # when building a 32 or 64 bit executable.
+ : options *
)
{
if $(command)
@@ -118,6 +148,7 @@
# 'configure' is a newer version of 'init'. The parameter 'command' is passed as
# a part of the 'options' list.
+#
rule configure ( version ? : options * )
{
switch $(version)
@@ -143,25 +174,39 @@
}
-# Supported CPU architectures
-cpu-arch-i386 =
+# Supported CPU architectures.
+.cpu-arch-i386 =
<architecture>/<address-model>
<architecture>/<address-model>32
<architecture>x86/<address-model>
<architecture>x86/<address-model>32 ;
-cpu-arch-amd64 =
+.cpu-arch-amd64 =
<architecture>/<address-model>64
<architecture>x86/<address-model>64 ;
-cpu-arch-ia64 =
+.cpu-arch-ia64 =
<architecture>ia64/<address-model>
<architecture>ia64/<address-model>64 ;
+# Locates the requested setup script under the given folder and returns its full
+# path or nothing in case the script can not be found. In case multiple scripts
+# are found only the first one is returned.
+#
+local rule locate-default-setup ( command : parent : setup-name )
+{
+ local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
+ if $(result[1])
+ {
+ return $(result[1]) ;
+ }
+}
+
+
local rule configure-really ( version ? : options * )
{
- # If no version supplied use the default configuration. Note that condition
+ # Note that if no version supplied uses the default configuration condition
# remains versionless.
local v = $(version) ;
if ! $(v)
@@ -185,37 +230,37 @@
# Check whether selected configuration is used already
if $(version) in [ $(.versions).used ]
{
- # Allow multiple 'toolset.usage' calls for the same configuration
- # if the identical sets of options are used
+ # Allow multiple 'toolset.using' calls for the same configuration if the
+ # identical sets of options are used.
if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
{
- errors.error "msvc: the toolset version '$(version)' is configured already" ;
+ errors.error "msvc: the toolset version '$(version)' already configured." ;
}
}
else
{
- # Register a new configuration
+ # Register a new configuration.
$(.versions).register $(version) ;
- # Add user-supplied to auto-detected options
+ # Add user-supplied to auto-detected options.
options = [ $(.versions).get $(version) : options ] $(options) ;
# Mark the configuration as 'used'.
$(.versions).use $(version) ;
- # Generate condition and save it
- local condition = [ common.check-init-parameters msvc : version $(v) ] ;
+ # Generate conditions and save them.
+ local conditions = [ common.check-init-parameters msvc : version $(v) ] ;
- $(.versions).set $(version) : condition : $(condition) ;
+ $(.versions).set $(version) : conditions : $(conditions) ;
local command = [ feature.get-values <command> : $(options) ] ;
# If version is specified, we try to search first in default paths, and
# only then in PATH.
- command = [ common.get-invocation-command msvc : cl.exe : $(command)
- : [ default-paths $(version) ] : $(version) ] ;
+ command = [ common.get-invocation-command msvc : cl.exe : $(command) :
+ [ default-paths $(version) ] : $(version) ] ;
- common.handle-options msvc : $(condition) : $(command) : $(options) ;
+ common.handle-options msvc : $(conditions) : $(command) : $(options) ;
if ! $(version)
{
@@ -251,81 +296,135 @@
local below-8.0 = [ MATCH ^([67]\\.) : $(version) ] ;
- local cpu = i386 ;
+ local cpu = i386 amd64 ia64 ;
+ if $(below-8.0)
+ {
+ cpu = i386 ;
+ }
- local setup ;
- local setup-option ;
+ local setup-amd64 ;
+ local setup-i386 ;
+ local setup-ia64 ;
if $(command)
{
+ # TODO: Note that if we specify a non-existant toolset version then
+ # this rule may find and use a corresponding compiler executable
+ # belonging to an incorrect toolset version. For example, if you
+ # have only MSVC 7.1 installed and specify you want Boost Build to
+ # use MSVC 9.0, then you want Boost Build to report an error but
+ # this may cause it to silently use the MSVC 7.1 compiler even
+ # though it thinks its using the msvc 9.0 toolset.
command = [ common.get-absolute-tool-path $(command[-1]) ] ;
local parent = [ path.make $(command) ] ;
parent = [ path.parent $(parent) ] ;
parent = [ path.native $(parent) ] ;
- # Setup will be used if the script name has been specified. If setup
- # is not specified, a default script will be used instead.
- setup = [ feature.get-values <setup> : $(options) ] ;
+ # Setup will be used if the command name has been specified. If
+ # setup is not specified explicitly then a default setup script will
+ # be used instead. Setup scripts may be global or arhitecture/
+ # /platform/cpu specific. Setup options are used only in case of
+ # global setup scripts.
+
+ # Default setup scripts provided with different VC distributions:
+ #
+ # VC 7.1 had only the vcvars32.bat script specific to 32 bit i386
+ # builds. It was located in the bin folder for the regular version
+ # and in the root folder for the free VC 7.1 tools.
+ #
+ # Later 8.0 & 9.0 versions introduce separate platform specific
+ # vcvars*.bat scripts (e.g. 32 bit, 64 bit AMD or 64 bit Itanium)
+ # located in or under the bin folder. Most also include a global
+ # vcvarsall.bat helper script located in the root folder which runs
+ # one of the aforementioned vcvars*.bat scripts based on the options
+ # passed to it. So far only the version coming with some PlatformSDK
+ # distributions does not include this top level script but to
+ # support those we need to fall back to using the worker scripts
+ # directly in case the top level script can not be found.
+
+ local global-setup = [ feature.get-values <setup> : $(options) ] ;
+ global-setup = $(global-setup[1]) ;
+ if ! $(below-8.0)
+ {
+ global-setup ?= [ locate-default-setup $(command) : $(parent) : vcvarsall.bat ] ;
+ }
- if ! $(setup)
+ local default-setup-amd64 = vcvarsx86_amd64.bat ;
+ local default-setup-i386 = vcvars32.bat ;
+ local default-setup-ia64 = vcvarsx86_ia64.bat ;
+
+ # http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx and
+ # http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx
+ # mention an x86_IPF option, that seems to be a documentation bug
+ # and x86_ia64 is the correct option.
+ local default-global-setup-options-amd64 = x86_amd64 ;
+ local default-global-setup-options-i386 = x86 ;
+ local default-global-setup-options-ia64 = x86_ia64 ;
+
+ # When using 64-bit Windows, and targeting 64-bit, it is possible to
+ # use a native 64-bit compiler, selected by the "amd64" & "ia64"
+ # parameters to vcvarsall.bat. There are two variables we can use --
+ # PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER. The first is
+ # 'x86' when running 32-bit Windows, no matter which processor is
+ # used, and 'AMD64' on 64-bit windows on x86 (either AMD64 or EM64T)
+ # Windows.
+ #
+ if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ]
{
- if $(below-8.0)
- {
- setup ?= vcvars32.bat ;
- }
- else
- {
- setup ?= vcvarsall.bat ;
- }
+ default-global-setup-options-amd64 = amd64 ;
+ }
+ # TODO: The same 'native compiler usage' should be implemented for
+ # the Itanium platform by using the "ia64" parameter. For this
+ # though we need someone with access to this platform who can find
+ # out how to correctly detect this case.
+ else if $(somehow-detect-the-itanium-platform)
+ {
+ default-global-setup-options-ia64 = ia64 ;
+ }
- # The vccars32.bat is actually in "bin" directory except for
- # free VC7.1 tools.
- setup = [ GLOB $(command) $(parent) : $(setup) ] ;
+ local setup-prefix = "call " ;
+ local setup-suffix = " >nul"$(nl) ;
+ if ! [ os.name ] in NT
+ {
+ setup-prefix = "cmd.exe /S /C call " ;
+ setup-suffix = " \">nul\" \"&&\" " ;
}
- if $(setup)
+ for local c in $(cpu)
{
- # Note Cygwin to Windows translation.
- setup = "\""$(setup[1]:W)"\"" ;
+ local setup-options ;
+
+ setup-$(c) = [ feature.get-values <setup-$(c)> : $(options) ] ;
- if ! $(below-8.0)
+ if ! $(setup-$(c))-is-not-empty
{
- cpu = i386 amd64 ia64 ;
- # Whereas http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx or
- # http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx
- # say about x86_IPF, that seem to be doc bug,
- # and x86_ia64 is right one.
- setup-option = x86 x86_amd64 x86_ia64 ;
-
- # When using 64-bit Windows, and targeting 64-bit, it's
- # possible to use native 64-bit compiler, which is selected
- # by the "amd64" parameter to vcvarsall.bat. There are two
- # variables we can use -- PROCESSOR_ARCHITECTURE and
- # PROCESSOR_IDENTIFIER. The first is 'x86' when running
- # 32-bit windows, no matter what processor is, and 'AMD64'
- # on 64-bit windows on x86 (either AMD64 or EM64T) windows.
- if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ]
+ if $(global-setup)-is-not-empty
+ {
+ setup-$(c) = $(global-setup) ;
+
+ # If needed we can easily add using configuration flags
+ # here for overriding which options get passed to the
+ # global setup command for which target platform:
+ # setup-options = [ feature.get-values <setup-options-$(c)> : $(options) ] ;
+
+ setup-options ?= $(default-global-setup-options-$(c)) ;
+ }
+ else
{
- setup-option = x86 amd64 x86_ia64 ;
+ setup-$(c) = [ locate-default-setup $(command) : $(parent) : $(default-setup-$(c)) ] ;
}
}
- }
- }
-
- local prefix = "call " ;
- local suffix = " >nul
-" ;
- if ! [ os.name ] in NT
- {
- prefix = "cmd.exe /S /C call " ;
- suffix = " >nul \"&&\" " ;
- }
- command = $(prefix)$(setup)" "$(setup-option:E="")$(suffix) ;
+ # Cygwin to Windows path translation.
+ setup-$(c) = "\""$(setup-$(c):W)"\"" ;
- # Setup script is not required in some configurations.
- command ?= "" ;
+ # Append setup options to the setup name and add the final setup
+ # prefix & suffix.
+ setup-options ?= "" ;
+ setup-$(c) = $(setup-prefix)$(setup-$(c):J=" ")" "$(setup-options:J=" ")$(setup-suffix) ;
+ }
+ }
# Get tool names (if any) and finish setup.
@@ -351,45 +450,45 @@
local cc-filter = [ feature.get-values <compiler-filter> : $(options) ] ;
- for local i in 1 2 3
+ for local c in $(cpu)
{
- local c = $(cpu[$(i)]) ;
+ # Setup script is not required in some configurations.
+ setup-$(c) ?= "" ;
- if $(c)
- {
- local cond = $(condition)/$(cpu-arch-$(c)) ;
+ local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ;
- if $(.debug-configuration)
+ if $(.debug-configuration)
+ {
+ for local cpu-condition in $(cpu-conditions)
{
- ECHO "msvc: condition: '$(cond)', "
- "command: '$(command[$(i)])'" ;
+ ECHO "msvc: condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ;
}
+ }
- toolset.flags msvc.compile .CC $(cond) : $(command[$(i)])$(compiler) /Zm800 -nologo ;
- toolset.flags msvc.compile .RC $(cond) : $(command[$(i)])$(resource-compiler) ;
- toolset.flags msvc.compile .ASM $(cond) : $(command[$(i)])$(assembler) ;
- toolset.flags msvc.link .LD $(cond) : $(command[$(i)])$(linker) /NOLOGO /INCREMENTAL:NO ;
- toolset.flags msvc.archive .LD $(cond) : $(command[$(i)])$(linker) /lib /NOLOGO ;
- toolset.flags msvc.compile .IDL $(cond) : $(command[$(i)])$(idl-compiler) ;
- toolset.flags msvc.compile .MC $(cond) : $(command[$(i)])$(mc-compiler) ;
+ toolset.flags msvc.compile .CC $(cpu-conditions) : $(setup-$(c))$(compiler) /Zm800 -nologo ;
+ toolset.flags msvc.compile .RC $(cpu-conditions) : $(setup-$(c))$(resource-compiler) ;
+ toolset.flags msvc.compile .ASM $(cpu-conditions) : $(setup-$(c))$(assembler) ;
+ toolset.flags msvc.link .LD $(cpu-conditions) : $(setup-$(c))$(linker) /NOLOGO /INCREMENTAL:NO ;
+ toolset.flags msvc.archive .LD $(cpu-conditions) : $(setup-$(c))$(linker) /lib /NOLOGO ;
+ toolset.flags msvc.compile .IDL $(cpu-conditions) : $(setup-$(c))$(idl-compiler) ;
+ toolset.flags msvc.compile .MC $(cpu-conditions) : $(setup-$(c))$(mc-compiler) ;
- if ! [ os.name ] in NT
- {
- toolset.flags msvc.link .MT $(cond) : $(command[$(i)])$(manifest-tool) -nologo ;
- }
- else
- {
- toolset.flags msvc.link .MT $(cond) : $(manifest-tool) -nologo ;
- }
+ if ! [ os.name ] in NT
+ {
+ toolset.flags msvc.link .MT $(cpu-conditions) : $(setup-$(c))$(manifest-tool) -nologo ;
+ }
+ else
+ {
+ toolset.flags msvc.link .MT $(cpu-conditions) : $(manifest-tool) -nologo ;
+ }
- if $(cc-filter)
- {
- toolset.flags msvc .CC.FILTER $(cond) : "|" $(cc-filter) ;
- }
+ if $(cc-filter)
+ {
+ toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
}
}
# Set version-specific flags.
- configure-version-specific msvc : $(version) : $(condition) ;
+ configure-version-specific msvc : $(version) : $(conditions) ;
}
}
@@ -416,10 +515,11 @@
# Sets up flag definitions dependent on the compiler version used.
# - 'version' is the version of compiler in N.M format.
-# - 'condition' is the property set to be used as condition for flag.
+# - 'conditions' is the property set to be used as flag conditions.
# - 'toolset' is the toolset for which flag settings are to be defined.
# This makes the rule reusable for other msvc-option-compatible compilers.
-rule configure-version-specific ( toolset : version : condition )
+#
+rule configure-version-specific ( toolset : version : conditions )
{
toolset.push-checking-for-flags-module unchecked ;
# Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
@@ -429,14 +529,20 @@
# 7.* explicitly, or if the installation path contain 7.* (checked above).
if ! [ MATCH ^(6\\.) : $(version) ]
{
- toolset.flags $(toolset).compile CFLAGS $(condition) : /Zc:forScope /Zc:wchar_t ;
- toolset.flags $(toolset).compile.c++ C++FLAGS $(condition) : /wd4675 ;
- # disable the function is deprecated warning
- # Some version of msvc have a bug, that cause deprecation
- # warning to be emitted even with /W0
- toolset.flags $(toolset).compile CFLAGS $(condition)/<warnings>off : /wd4996 ;
- # 64-bit compatibility warning
- toolset.flags $(toolset).compile CFLAGS $(condition)/<warnings>all : /Wp64 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions) : /Zc:forScope /Zc:wchar_t ;
+ toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ;
+
+ # Explicitly disable the 'function is deprecated' warning. Some msvc
+ # versions have a bug, causing them to emit the deprecation warning even
+ # with /W0.
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>off : /wd4996 ;
+
+ if [ MATCH ^([78]\\.) : $(version) ]
+ {
+ # 64-bit compatibility warning deprecated since 9.0, see
+ # http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>all : /Wp64 ;
+ }
}
#
@@ -446,41 +552,42 @@
if [ MATCH ^([67]) : $(version) ]
{
# 8.0 deprecates some of the options.
- toolset.flags $(toolset).compile CFLAGS $(condition)/<optimization>speed $(condition)/<optimization>space : /Ogiy /Gs ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/<optimization>speed : /Ot ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/<optimization>space : /Os ;
-
- toolset.flags $(toolset).compile CFLAGS $(condition)/$(cpu-arch-i386)/<instruction-set> : /GB ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/$(cpu-arch-i386)/<instruction-set>i386 : /G3 ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/$(cpu-arch-i386)/<instruction-set>i486 : /G4 ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/$(cpu-arch-i386)/<instruction-set>$(cpu-type-g5) : /G5 ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/$(cpu-arch-i386)/<instruction-set>$(cpu-type-g6) : /G6 ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/$(cpu-arch-i386)/<instruction-set>$(cpu-type-g7) : /G7 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed : /Ot ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>space : /Os ;
+
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i386 : /G3 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(cpu-type-g5) : /G5 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(cpu-type-g6) : /G6 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(cpu-type-g7) : /G7 ;
# Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
# tests will fail.
- toolset.flags $(toolset).compile CFLAGS $(condition) : /Op ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions) : /Op ;
# 7.1 and below have single-threaded static RTL.
- toolset.flags $(toolset).compile CFLAGS $(condition)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
}
else
{
# 8.0 and above adds some more options.
- toolset.flags $(toolset).compile CFLAGS $(condition)/$(cpu-arch-amd64)/<instruction-set> : /favor:blend ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/$(cpu-arch-amd64)/<instruction-set>$(cpu-type-em64t) : /favor:EM64T ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/$(cpu-arch-amd64)/<instruction-set>$(cpu-type-amd64) : /favor:AMD64 ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : /favor:blend ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(cpu-type-em64t) : /favor:EM64T ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(cpu-type-amd64) : /favor:AMD64 ;
# 8.0 and above only has multi-threaded static RTL.
- toolset.flags $(toolset).compile CFLAGS $(condition)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
- toolset.flags $(toolset).compile CFLAGS $(condition)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ;
}
toolset.pop-checking-for-flags-module ;
}
# Returns the default installation path for the given version.
+#
local rule default-path ( version )
{
# Use auto-detected path if possible
@@ -520,6 +627,7 @@
# Returns either the default installation path (if 'version' is not empty) or
# list of all known default paths (if no version is given)
+#
rule default-paths ( version ? )
{
local possible-paths ;
@@ -542,8 +650,8 @@
# Declare generators.
-# Is it possible to combine these? Make the generators non-composing so that
-# they don't convert each source into a separate rsp file.
+# TODO: Is it possible to combine these? Make the generators non-composing so
+# that they do not convert each source into a separate .rsp file.
generators.register-linker msvc.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ;
generators.register-linker msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB : <toolset>msvc ;
@@ -572,7 +680,7 @@
rule run-pch ( project name ? : property-set : sources * )
{
- # searching header and source file in the sources
+ # Searching header and source file in the sources.
local pch-header ;
local pch-source ;
for local s in $(sources)
@@ -643,8 +751,8 @@
flags msvc.compile CFLAGS <optimization>speed : /O2 ;
flags msvc.compile CFLAGS <optimization>space : /O1 ;
-flags msvc.compile CFLAGS $(cpu-arch-ia64)/<instruction-set>$(cpu-type-itanium) : /G1 ;
-flags msvc.compile CFLAGS $(cpu-arch-ia64)/<instruction-set>$(cpu-type-itanium2) : /G2 ;
+flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(cpu-type-itanium) : /G1 ;
+flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(cpu-type-itanium2) : /G2 ;
flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ;
flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ;
@@ -686,7 +794,7 @@
rule get-rspline ( target : lang-opt )
{
- CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS) $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(nl)-D$(DEFINES) $(nl)\"-I$(INCLUDES)\" ] ;
+ CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS) $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(nl)-D$(DEFINES) $(nl)\"-I$(INCLUDES:W)\" ] ;
}
@@ -771,7 +879,7 @@
actions compile.rc
{
- $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES)" -fo "$(<:W)" "$(>:W)"
+ $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
}
@@ -781,7 +889,7 @@
actions compile.idl
{
- $(.IDL) /nologo @"@($(<[1]:W).rsp:E=$(nl)"$(>:W)" $(nl)-D$(DEFINES) $(nl)"-I$(INCLUDES)" $(nl)-U$(UNDEFS) $(nl)$(MIDLFLAGS) $(nl)/tlb "$(<[1]:W)" $(nl)/h "$(<[2]:W)" $(nl)/iid "$(<[3]:W)" $(nl)/proxy "$(<[4]:W)" $(nl)/dlldata "$(<[5]:W)")"
+ $(.IDL) /nologo @"@($(<[1]:W).rsp:E=$(nl)"$(>:W)" $(nl)-D$(DEFINES) $(nl)"-I$(INCLUDES:W)" $(nl)-U$(UNDEFS) $(nl)$(MIDLFLAGS) $(nl)/tlb "$(<[1]:W)" $(nl)/h "$(<[2]:W)" $(nl)/iid "$(<[3]:W)" $(nl)/proxy "$(<[4]:W)" $(nl)/dlldata "$(<[5]:W)")"
$(TOUCH_FILE) "$(<[4]:W)"
$(TOUCH_FILE) "$(<[5]:W)"
}
@@ -835,6 +943,7 @@
DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
}
+
# Declare action for creating static libraries. If library exists, remove it
# before adding files. See
# http://article.gmane.org/gmane.comp.lib.boost.build/4241 for rationale.
@@ -859,9 +968,9 @@
# Incremental linking a DLL causes no end of problems: if the actual exports
-# don't change, the import .lib file is never updated. Therefore, the .lib is
+# do not change, the import .lib file is never updated. Therefore, the .lib is
# always out-of-date and gets rebuilt every time. I'm not sure that incremental
-# linking is such a great idea in general, but in this case I'm sure we don't
+# linking is such a great idea in general, but in this case I am sure we do not
# want it.
# Windows manifest is a new way to specify dependencies on managed DotNet
@@ -954,6 +1063,7 @@
# Validates given path, registers found configuration and prints debug
# information about it.
+#
local rule register-configuration ( version : path ? )
{
if $(path)
Modified: branches/release/tools/build/v2/tools/pathscale.jam
==============================================================================
--- branches/release/tools/build/v2/tools/pathscale.jam (original)
+++ branches/release/tools/build/v2/tools/pathscale.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -41,6 +41,9 @@
toolset.flags pathscale CONFIG_F_COMMAND $(condition) : $(command_f) ;
toolset.flags pathscale CONFIG_F90_COMMAND $(condition) : $(command_f90) ;
+
+ # always link lib rt to resolve clock_gettime()
+ flags pathscale.link FINDLIBS-SA : rt : unchecked ;
}
# Declare generators
@@ -112,7 +115,6 @@
flags pathscale.link FINDLIBS-ST <find-static-library> ;
flags pathscale.link FINDLIBS-SA <find-shared-library> ;
flags pathscale.link FINDLIBS-SA <threading>multi : pthread ;
-flags pathscale.link FINDLIBS-SA <threading>multi : rt ;
flags pathscale.link LIBRARIES <library-file> ;
flags pathscale.link LINK-RUNTIME <runtime-link>static : static ;
flags pathscale.link LINK-RUNTIME <runtime-link>shared : dynamic ;
Modified: branches/release/tools/build/v2/tools/pgi.jam
==============================================================================
--- branches/release/tools/build/v2/tools/pgi.jam (original)
+++ branches/release/tools/build/v2/tools/pgi.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -36,11 +36,15 @@
flags pgi.compile DEFINES $(condition) :
[ feature.get-values <define> : $(options) ] : unchecked ;
+ # IOV_MAX support
+ flags pgi.compile DEFINES $(condition) : __need_IOV_MAX : unchecked ;
+
# set link flags
flags pgi.link FINDLIBS-ST : [
feature.get-values <find-static-library> : $(options) ] : unchecked ;
- flags pgi.link FINDLIBS-SA : [
+ # always link lib rt to resolve clock_gettime()
+ flags pgi.link FINDLIBS-SA : rt [
feature.get-values <find-shared-library> : $(options) ] : unchecked ;
gcc.init-link-flags pgi gnu $(condition) ;
Modified: branches/release/tools/build/v2/tools/python.jam
==============================================================================
--- branches/release/tools/build/v2/tools/python.jam (original)
+++ branches/release/tools/build/v2/tools/python.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -7,11 +7,11 @@
#
# This module defines
#
-# - a project 'python' with a target 'python' in it, that corresponds
-# to the python library
+# - a project 'python' with a target 'python' in it, that corresponds to the
+# python library
#
-# - a main target rule 'python-extension' which can be used
-# to build a python extension.
+# - a main target rule 'python-extension' which can be used to build a python
+# extension.
#
# Extensions that use Boost.Python must explicitly link to it.
@@ -24,7 +24,7 @@
import "class" : new ;
import os ;
import common ;
-import toolset : flags ;
+import toolset ;
import regex ;
import numbers ;
import string ;
@@ -34,21 +34,21 @@
import feature ;
import set ;
import builtin ;
+import version ;
-# Make this module a project
+
+# Make this module a project.
project.initialize $(__name__) ;
project python ;
-# Save the project so that if 'init' is called several
-# times we define new targets in the python project,
-# not in whatever project we were called by.
+# Save the project so that if 'init' is called several times we define new
+# targets in the python project, not in whatever project we were called by.
.project = [ project.current ] ;
-# Dynamic linker lib. Necessary to specify it explicitly
-# on some platforms.
+# Dynamic linker lib. Necessary to specify it explicitly on some platforms.
lib dl ;
-# This contains 'openpty' function need by python. Again, on
-# some system need to pass this to linker explicitly.
+# This contains 'openpty' function need by python. Again, on some system need to
+# pass this to linker explicitly.
lib util ;
# Python uses pthread symbols.
lib pthread ;
@@ -56,44 +56,38 @@
lib rt ;
# The pythonpath feature specifies additional elements for the PYTHONPATH
-# environment variable, set by run-pyd. For example, pythonpath can be used
-# to access Python modules that are part of the product being built, but
-# are not installed in the development system's default paths.
+# environment variable, set by run-pyd. For example, pythonpath can be used to
+# access Python modules that are part of the product being built, but are not
+# installed in the development system's default paths.
feature.feature pythonpath : : free optional path ;
-# Initializes the Python toolset. Note that all parameters are
-# optional.
+# Initializes the Python toolset. Note that all parameters are optional.
+#
+# - version -- the version of Python to use. Should be in Major.Minor format,
+# for example 2.3. Do not include the subminor version.
+#
+# - cmd-or-prefix: Preferably, a command that invokes a Python interpreter.
+# Alternatively, the installation prefix for Python libraries and includes. If
+# empty, will be guessed from the version, the platform's installation
+# patterns, and the python executables that can be found in PATH.
+#
+# - includes: the include path to Python headers. If empty, will be guessed.
+#
+# - libraries: the path to Python library binaries. If empty, will be guessed.
+# On MacOS/Darwin, you can also pass the path of the Python framework.
#
-# - version -- the version of Python to use. Should be in Major.Minor
-# format, for example 2.3. Do not include the subminor version.
+# - condition: if specified, should be a set of properties that are matched
+# against the build configuration when Boost.Build selects a Python
+# configuration to use.
#
-# - cmd-or-prefix: Preferably, a command that invokes a Python
-# interpreter. Alternatively, the installation prefix for Python
-# libraries and includes. If empty, will be guessed from the
-# version, the platform's installation patterns, and the python
-# executables that can be found in PATH.
-#
-# - includes: the include path to Python headers. If empty, will be
-# guessed.
-#
-# - libraries: the path to Python library binaries. If empty, will be
-# guessed. On MacOS/Darwin, you can also pass the path of the
-# Python framework.
-#
-# - condition: if specified, should be a set of properties that are
-# matched against the build configuration when Boost.Build selects a
-# Python configuration to use.
-#
-# - extension-suffix: A string to append to the name of extension
-# modules before the true filename extension. Ordinarily we would
-# just compute this based on the value of the <python-debugging>
-# feature. However ubuntu's python-dbg package uses the windows
-# convention of appending _d to debug-build extension modules. We
-# have no way of detecting ubuntu, or of probing python for the "_d"
-# requirement, and if you configure and build python using
-# --with-pydebug, you'll be using the standard *nix convention.
-# Defaults to "" (or "_d" when targeting windows and
-# <python-debugging> is set).
+# - extension-suffix: A string to append to the name of extension modules before
+# the true filename extension. Ordinarily we would just compute this based on
+# the value of the <python-debugging> feature. However ubuntu's python-dbg
+# package uses the windows convention of appending _d to debug-build extension
+# modules. We have no way of detecting ubuntu, or of probing python for the
+# "_d" requirement, and if you configure and build python using
+# --with-pydebug, you'll be using the standard *nix convention. Defaults to ""
+# (or "_d" when targeting windows and <python-debugging> is set).
#
# Example usage:
#
@@ -119,8 +113,9 @@
project.pop-current ;
}
-# A simpler version of SHELL that grabs stderr as well as stdout, but
-# returns nothing if there's an error.
+# A simpler version of SHELL that grabs stderr as well as stdout, but returns
+# nothing if there was an error.
+#
local rule shell-cmd ( cmd )
{
debug-message running command '$(cmd)" 2>&1"' ;
@@ -135,34 +130,34 @@
}
}
-# Try to identify Cygwin symlinks. Invoking such a file directly as
-# an NT executable from a native Windows build of bjam would be fatal
-# to the bjam process. One /can/ invoke them through sh.exe or
-# bash.exe, if you can prove that those aren't also symlinks ;-)
+
+# Try to identify Cygwin symlinks. Invoking such a file directly as an NT
+# executable from a native Windows build of bjam would be fatal to the bjam
+# process. One /can/ invoke them through sh.exe or bash.exe, if you can prove
+# that those are not also symlinks. ;-)
#
-# If a symlink is found returns non-empty; we try to extract the
-# target of the symlink from the file and return that.
+# If a symlink is found returns non-empty; we try to extract the target of the
+# symlink from the file and return that.
#
# Note: 1. only works on NT 2. path is a native path.
local rule is-cygwin-symlink ( path )
{
local is-symlink = ;
- # Look for a file with the given path having the S attribute set,
- # as cygwin symlinks do. /-C means "do not use thousands
- # separators in file sizes."
- local dir-listing = [ shell-cmd "DIR /-C /A:S "$(path) ] ;
+ # Look for a file with the given path having the S attribute set, as cygwin
+ # symlinks do. /-C means "do not use thousands separators in file sizes."
+ local dir-listing = [ shell-cmd "DIR /-C /A:S \""$(path)"\"" ] ;
if $(dir-listing)
{
- # escape any special regex characters in the base part of the path
+ # Escape any special regex characters in the base part of the path.
local base-pat = [ regex.escape $(path:D=) : ].[()*+?|\\$^ : \\ ] ;
- # extract the file's size from the directory listing
+ # Extract the file's size from the directory listing.
local size-of-system-file = [ MATCH "([0-9]+) "$(base-pat) : $(dir-listing) : 1 ] ;
- # if the file has a reasonably small size, look for the
- # special symlink identification text
+ # If the file has a reasonably small size, look for the special symlink
+ # identification text.
if $(size-of-system-file) && [ numbers.less $(size-of-system-file) 1000 ]
{
local link = [ SHELL "FIND /OFF \"!<symlink>\" \""$(path)"\" 2>&1" ] ;
@@ -184,7 +179,9 @@
return $(is-symlink) ;
}
-# Append ext to each member of names that does not contain '.'
+
+# Append ext to each member of names that does not contain '.'.
+#
local rule default-extension ( names * : ext * )
{
local result ;
@@ -199,10 +196,12 @@
return $(result) ;
}
-# Tries to determine whether invoking "cmd" would actually attempt to
-# launch a cygwin symlink.
+
+# Tries to determine whether invoking "cmd" would actually attempt to launch a
+# cygwin symlink.
+#
+# Note: only works on NT.
#
-# Note: only works on NT
local rule invokes-cygwin-symlink ( cmd )
{
local dirs = $(cmd:D) ;
@@ -210,16 +209,17 @@
{
dirs = . [ os.executable-path ] ;
}
- local base = [ default-extension $(cmd:D=) : .exe .bat ] ;
+ local base = [ default-extension $(cmd:D=) : .exe .cmd .bat ] ;
local paths = [ GLOB $(dirs) : $(base) ] ;
if $(paths)
{
- # Make sure we didn't find a Cygwin symlink. Invoking such a
- # file as an NT executable will be fatal to the bjam process.
+ # Make sure we have not run into a Cygwin symlink. Invoking such a file
+ # as an NT executable would be fatal for the bjam process.
return [ is-cygwin-symlink $(paths[1]) ] ;
}
}
+
local rule debug-message ( message * )
{
if --debug-configuration in [ modules.peek : ARGV ]
@@ -228,11 +228,12 @@
}
}
+
# Like W32_GETREG, except prepend HKEY_CURRENT_USER\SOFTWARE and
-# HKEY_LOCAL_MACHINE\SOFTWARE to the first argument, returning the
-# first result found. Also accounts for the fact that on 64-bit
-# machines, 32-bit software has its own area, under
-# SOFTWARE\Wow6432node.
+# HKEY_LOCAL_MACHINE\SOFTWARE to the first argument, returning the first result
+# found. Also accounts for the fact that on 64-bit machines, 32-bit software has
+# its own area, under SOFTWARE\Wow6432node.
+#
local rule software-registry-value ( path : data ? )
{
local result ;
@@ -250,6 +251,7 @@
return $(result) ;
}
+
.windows-drive-letter-re = ^([A-Za-z]):[\\/](.*) ;
.cygwin-drive-letter-re = ^/cygdrive/([a-z])/(.*) ;
@@ -257,21 +259,23 @@
.working-drive-letter = [ SUBST $(.working-directory) $(.windows-drive-letter-re) $1 ] ;
.working-drive-letter ?= [ SUBST $(.working-directory) $(.cygwin-drive-letter-re) $1 ] ;
+
local rule windows-to-cygwin-path ( path )
{
- # if path is rooted with a drive letter, rewrite it using the
- # /cygdrive mountpoint
+ # If path is rooted with a drive letter, rewrite it using the /cygdrive
+ # mountpoint.
local p = [ SUBST $(path:T) $(.windows-drive-letter-re) /cygdrive/$1/$2 ] ;
- # else if path is rooted without a drive letter, use the working directory
- p ?= [ SUBST $(path:T) ^/(.*) /cygdrive/$(.working-drive-letter:L)/$2 ] ;
+ # Else if path is rooted without a drive letter, use the working directory.
+ p ?= [ SUBST $(path:T) ^/(.*) /cygdrive/$(.working-drive-letter:L)/$2 ] ;
- # else return the path unchanged
+ # Else return the path unchanged.
return $(p:E=$(path:T)) ;
}
-# :W only works in Cygwin builds of bjam. This one works on NT builds
-# as well.
+
+# :W only works in Cygwin builds of bjam. This one works on NT builds as well.
+#
local rule cygwin-to-windows-path ( path )
{
path = $(path:R="") ; # strip any trailing slash
@@ -289,10 +293,8 @@
while $(head)
{
- local root = [
- software-registry-value "Cygnus Solutions\\Cygwin\\mounts v2\\"$(head)
- : native
- ] ;
+ local root = [ software-registry-value
+ "Cygnus Solutions\\Cygwin\\mounts v2\\"$(head) : native ] ;
if $(root)
{
@@ -314,7 +316,9 @@
return [ regex.replace $(path:R="") / \\ ] ;
}
-# Convert a *nix path to native
+
+# Convert a *nix path to native.
+#
local rule *nix-path-to-native ( path )
{
if [ os.name ] = NT
@@ -324,7 +328,9 @@
return $(path) ;
}
-# Convert an NT path to native
+
+# Convert an NT path to native.
+#
local rule windows-path-to-native ( path )
{
if [ os.name ] = NT
@@ -337,13 +343,16 @@
}
}
-# Return nonempty if path looks like a windows path, i.e. it starts
-# with a drive letter or contains backslashes.
+
+# Return nonempty if path looks like a windows path, i.e. it starts with a drive
+# letter or contains backslashes.
+#
local rule guess-windows-path ( path )
{
return [ SUBST $(path) ($(.windows-drive-letter-re)|.*([\\]).*) $1 ] ;
}
+
local rule path-to-native ( paths * )
{
local result ;
@@ -362,8 +371,9 @@
return $(result) ;
}
-# Validate the version string and extract the major/minor part we care
-# about
+
+# Validate the version string and extract the major/minor part we care about.
+#
local rule split-version ( version )
{
local major-minor = [ MATCH ^([0-9]+)\.([0-9]+)(.*)$ : $(version) : 1 2 3 ] ;
@@ -378,16 +388,18 @@
return $(major-minor[1]) $(major-minor[2]) ;
}
-# Build a list of versions from 3.0 down to 1.5. Because bjam
-# can't enumerate registry sub-keys, we have no way of finding
-# a version with a 2-digit minor version, e.g. 2.10 -- let's
-# hope that never happens.
+
+# Build a list of versions from 3.0 down to 1.5. Because bjam can not enumerate
+# registry sub-keys, we have no way of finding a version with a 2-digit minor
+# version, e.g. 2.10 -- let us hope that never happens.
+#
.version-countdown = ;
for local v in [ numbers.range 15 30 ]
{
.version-countdown = [ SUBST $(v) (.)(.*) $1.$2 ] $(.version-countdown) ;
}
+
local rule windows-installed-pythons ( version ? )
{
version ?= $(.version-countdown) ;
@@ -409,6 +421,7 @@
return $(interpreters) ;
}
+
local rule darwin-installed-pythons ( version ? )
{
version ?= $(.version-countdown) ;
@@ -420,12 +433,14 @@
return $(prefix)/Versions/$(version)/bin/python ;
}
-# Assume "python-cmd" invokes a python interpreter and invoke it to
-# extract all the information we care about from its "sys" module.
-# Returns void if unsuccessful.
+
+# Assume "python-cmd" invokes a python interpreter and invoke it to extract all
+# the information we care about from its "sys" module. Returns void if
+# unsuccessful.
+#
local rule probe ( python-cmd )
{
- # Avoid invoking a Cygwin symlink on NT
+ # Avoid invoking a Cygwin symlink on NT.
local skip-symlink ;
if [ os.name ] = NT
{
@@ -441,19 +456,17 @@
debug-message If you intend to target a Cygwin build of Python, please ;
debug-message replace the path to the link with the path to a real executable ;
debug-message (guessing: \"$(skip-symlink)\") "in" your 'using python' line ;
- debug-message "in" user-config.jam or site-config.jam. Don't forget to escape ;
+ debug-message "in" user-config.jam or site-config.jam. Do not forget to escape ;
debug-message backslashes ;
debug-message -------------------------------------------------------------------- ;
}
else
{
- # Prepare a List of Python format strings and expressions that
- # can be used to print the constants we want from the sys
- # module.
-
- # We don't really want sys.version since that's a complicated
- # string, so get the information from sys.version_info
- # instead.
+ # Prepare a List of Python format strings and expressions that can be
+ # used to print the constants we want from the sys module.
+
+ # We do not really want sys.version since that is a complicated string,
+ # so get the information from sys.version_info instead.
local format = "version=%d.%d" ;
local exprs = "version_info[0]" "version_info[1]" ;
@@ -463,22 +476,29 @@
exprs += $(s) ;
}
- # Invoke Python and ask it for all those values
+ # Invoke Python and ask it for all those values.
+ if [ version.check-jam-version 3 1 17 ] || ( [ os.name ] != NT )
+ {
+ # Prior to version 3.1.17 Boost Jam's SHELL command did not support
+ # quoted commands correctly on Windows. This means that on that
+ # platform we do not support using a Python command interpreter
+ # executable whose path contains a space character.
+ python-cmd = \"$(python-cmd)\" ;
+ }
local full-cmd =
- $(python-cmd)" -c \"from sys import *; print '"$(format:J=\\n)"' % ("$(exprs:J=,)")\"" ;
+ $(python-cmd)" -c \"from sys import *; print '"$(format:J=\\n)"' % ("$(exprs:J=,)")\"" ;
local output = [ shell-cmd $(full-cmd) ] ;
if $(output)
{
- # Parse the output to get all the results
+ # Parse the output to get all the results.
local nl = "
" ;
for s in $(sys-elements)
{
- # These variables are expected to be declared local in
- # the caller, so Jam's dynamic scoping will set their
- # values there.
+ # These variables are expected to be declared local in the
+ # caller, so Jam's dynamic scoping will set their values there.
sys.$(s) = [ SUBST $(output) \\<$(s)=([^$(nl)]+) $1 ] ;
}
}
@@ -486,30 +506,29 @@
}
}
-# Make sure the "libraries" and "includes" variables (in an enclosing
-# scope) have a value based on the information given.
-local rule compute-default-paths (
- target-os : version ? : prefix ? : exec-prefix ? )
+
+# Make sure the "libraries" and "includes" variables (in an enclosing scope)
+# have a value based on the information given.
+#
+local rule compute-default-paths ( target-os : version ? : prefix ? :
+ exec-prefix ? )
{
exec-prefix ?= $(prefix) ;
if $(target-os) = windows
{
- # The exec_prefix is where you're supposed to look for
- # machine-specific libraries.
+ # The exec_prefix is where you're supposed to look for machine-specific
+ # libraries.
local default-library-path = $(exec-prefix)\\libs ;
local default-include-path = $(:E=Include:R=$(prefix)) ;
- # If the interpreter was found in a directory
- # called "PCBuild" or "PCBuild8," assume we're
- # looking at a Python built from the source
- # distro, and go up one additional level to the
- # default root. Otherwise, the default root is
- # the directory where the interpreter was found.
-
- # We ask Python itself what the executable path is
- # in case of intermediate symlinks or shell
- # scripts.
+ # If the interpreter was found in a directory called "PCBuild" or
+ # "PCBuild8," assume we're looking at a Python built from the source
+ # distro, and go up one additional level to the default root. Otherwise,
+ # the default root is the directory where the interpreter was found.
+
+ # We ask Python itself what the executable path is in case of
+ # intermediate symlinks or shell scripts.
local executable-dir = $(sys.executable:D) ;
if [ MATCH ^(PCBuild) : $(executable-dir:D=) ]
@@ -517,8 +536,7 @@
debug-message "This Python appears to reside in a source distribution;" ;
debug-message "prepending \""$(executable-dir)"\" to default library search path" ;
- default-library-path = $(executable-dir)
- $(default-library-path) ;
+ default-library-path = $(executable-dir) $(default-library-path) ;
default-include-path = $(:E=PC:R=$(executable-dir:D)) $(default-include-path) ;
@@ -537,11 +555,11 @@
}
}
-# The version of the python interpreter to use
+# The version of the python interpreter to use.
feature.feature python : : propagated ;
feature.feature python.interpreter : : free ;
-flags python.capture-output PYTHON : <python.interpreter> ;
+toolset.flags python.capture-output PYTHON : <python.interpreter> ;
#
# Support for Python configured --with-pydebug
@@ -549,79 +567,78 @@
feature.feature python-debugging : off on : propagated ;
builtin.variant debug-python : debug : <python-debugging>on ;
+
# Return a list of candidate commands to try when looking for a Python
-# interpreter. prefix is expected to be a native path.
+# interpreter. prefix is expected to be a native path.
+#
local rule candidate-interpreters ( version ? : prefix ? : target-os )
{
local bin-path = bin ;
if $(target-os) = windows
{
- # on Windows, look in the root directory itself and, to work
- # with the result of a build-from-source, the PCBuild directory
- bin-path = PCBuild8 PCBuild "" ;
+ # On Windows, look in the root directory itself and, to work with the
+ # result of a build-from-source, the PCBuild directory.
+ bin-path = PCBuild8 PCBuild "" ;
}
bin-path = $(bin-path:R=$(prefix)) ;
if $(target-os) in windows darwin
{
- return # Search:
- $(:E=python:R=$(bin-path)) # Relative to the prefix, if any
- python # In the PATH
- [ $(target-os)-installed-pythons $(version) ] # Standard install locations
+ return # Search:
+ $(:E=python:R=$(bin-path)) # Relative to the prefix, if any
+ python # In the PATH
+ [ $(target-os)-installed-pythons $(version) ] # Standard install locations
;
}
else
{
- # Search relative to the prefix, or if none supplied, in PATH
+ # Search relative to the prefix, or if none supplied, in PATH.
local unversioned = $(:E=python:R=$(bin-path:E=)) ;
- # if a version was specified, look for a python with that
- # specific version appended before looking for one called,
- # simply, "python"
+ # If a version was specified, look for a python with that specific
+ # version appended before looking for one called, simply, "python"
return $(unversioned)$(version) $(unversioned) ;
}
}
-# Compute system library dependencies for targets linking with
-# static Python libraries.
+
+# Compute system library dependencies for targets linking with static Python
+# libraries.
#
-# On many systems, Python uses libraries such as pthreads or
-# libdl. Since static libraries carry no library dependency
-# information of their own that the linker can extract, these
-# extra dependencies have to be given explicitly on the link line
-# of the client. The information about these dependencies is
-# packaged into the "python" target below.
-
-# Even where Python itself uses pthreads, it never allows
-# extension modules to be entered concurrently (unless they
-# explicitly give up the interpreter lock). Therefore, extension
-# modules don't need the efficiency overhead of threadsafe code as
-# produced by <threading>multi, and we handle libpthread along
-# with other libraries here. Note: this optimization is based on
-# an assumption that the compiler generates link-compatible code
-# in both the single- and multi-threaded cases, and that system
-# libraries don't change their ABIs either.
+# On many systems, Python uses libraries such as pthreads or libdl. Since static
+# libraries carry no library dependency information of their own that the linker
+# can extract, these extra dependencies have to be given explicitly on the link
+# line of the client. The information about these dependencies is packaged into
+# the "python" target below.
+#
+# Even where Python itself uses pthreads, it never allows extension modules to
+# be entered concurrently (unless they explicitly give up the interpreter lock).
+# Therefore, extension modules do not need the efficiency overhead of threadsafe
+# code as produced by <threading>multi, and we handle libpthread along with
+# other libraries here. Note: this optimization is based on an assumption that
+# the compiler generates link-compatible code in both the single- and
+# multi-threaded cases, and that system libraries do not change their ABIs
+# either.
+#
+# Returns a list of usage-requirements that link to the necessary system
+# libraries.
#
-# Returns a list of usage-requirements that link to the necessary
-# system libraries.
local rule system-library-dependencies ( target-os )
{
switch $(target-os)
{
case s[uo][nl]* : # solaris, sun, sunos
- # Add a librt dependency for the gcc toolset on SunOS (the
- # sun toolset adds -lrt unconditionally). While this
- # appears to duplicate the logic already in gcc.jam, it
- # doesn't as long as we're not forcing <threading>multi.
-
- # On solaris 10,
- # distutils.sysconfig.get_config_var('LIBS') yields
- # '-lresolv -lsocket -lnsl -lrt -ldl'. However, that
- # doesn't seem to be the right list for extension modules.
- # For example, on my installation, adding -ldl causes at
- # least one test to fail because the library can't be
- # found and removing it causes no failures.
+ # Add a librt dependency for the gcc toolset on SunOS (the sun
+ # toolset adds -lrt unconditionally). While this appears to
+ # duplicate the logic already in gcc.jam, it does not as long as
+ # we are not forcing <threading>multi.
+
+ # On solaris 10, distutils.sysconfig.get_config_var('LIBS') yields
+ # '-lresolv -lsocket -lnsl -lrt -ldl'. However, that does not seem
+ # to be the right list for extension modules. For example, on my
+ # installation, adding -ldl causes at least one test to fail because
+ # the library can not be found and removing it causes no failures.
# Apparently, though, we need to add -lrt for gcc.
return <toolset>gcc:<library>rt ;
@@ -640,11 +657,13 @@
}
}
+
# Declare a target to represent Python's library.
+#
local rule declare-libpython-target ( version ? : requirements * )
{
- # Compute the representation of Python version in the name of
- # Python's library file.
+ # Compute the representation of Python version in the name of Python's
+ # library file.
local lib-version = $(version) ;
if <target-os>windows in $(requirements)
{
@@ -664,13 +683,14 @@
ECHO *** warning: to 'using python'. ;
}
- # Declare it
+ # Declare it.
lib python.lib : : <name>python$(lib-version) $(requirements) ;
}
-# implementation of init
-local rule configure (
- version ? : cmd-or-prefix ? : includes * : libraries ? : condition * : extension-suffix ? )
+
+# Implementation of init.
+local rule configure ( version ? : cmd-or-prefix ? : includes * : libraries ? :
+ condition * : extension-suffix ? )
{
local prefix ;
local exec-prefix ;
@@ -687,7 +707,7 @@
}
extension-suffix ?= "" ;
- # Normalize and dissect any version number
+ # Normalize and dissect any version number.
local major-minor ;
if $(version)
{
@@ -699,7 +719,7 @@
if ! $(cmd-or-prefix) || [ GLOB $(cmd-or-prefix) : * ]
{
- # if the user didn't pass a command, whatever we got was a prefix
+ # If the user did not pass a command, whatever we got was a prefix.
prefix = $(cmd-or-prefix) ;
cmds-to-try = [ candidate-interpreters $(version) : $(prefix) : $(target-os) ] ;
}
@@ -708,31 +728,31 @@
# Work with the command the user gave us.
cmds-to-try = $(cmd-or-prefix) ;
- # On windows, don't nail down the interpreter command just yet
- # in case the user specified something that turns out to be a
- # cygwin symlink, which could bring down bjam if we invoke it.
+ # On Windows, do not nail down the interpreter command just yet in case
+ # the user specified something that turns out to be a cygwin symlink,
+ # which could bring down bjam if we invoke it.
if $(target-os) != windows
{
interpreter-cmd = $(cmd-or-prefix) ;
}
}
- # Values to use in case we can't really find anything in the system.
+ # Values to use in case we can not really find anything in the system.
local fallback-cmd = $(cmds-to-try[1]) ;
local fallback-version ;
# Anything left to find or check?
if ! ( $(interpreter-cmd) && $(includes) && $(libraries) )
{
- # Values to be extracted from python's sys module. These will
- # be set by the probe rule, above, using Jam's dynamic scoping.
+ # Values to be extracted from python's sys module. These will be set by
+ # the probe rule, above, using Jam's dynamic scoping.
local sys-elements = version platform prefix exec_prefix executable ;
local sys.$(sys-elements) ;
- # compute the string Python's sys.platform needs to match. If
- # not targeting windows or cygwin we'll assume only native
- # builds can possibly run, so we won't require a match and we
- # leave sys.platform blank.
+ # Compute the string Python's sys.platform needs to match. If not
+ # targeting Windows or cygwin we will assume only native builds can
+ # possibly run, so we will not require a match and we leave sys.platform
+ # blank.
local platform ;
switch $(target-os)
{
@@ -742,7 +762,7 @@
while $(cmds-to-try)
{
- # pop top command
+ # Pop top command.
local cmd = $(cmds-to-try[1]) ;
cmds-to-try = $(cmds-to-try[2-]) ;
@@ -751,7 +771,7 @@
{
fallback-version ?= $(sys.version) ;
- # Check for version/platform validity
+ # Check for version/platform validity.
for local x in version platform
{
if $($(x)) && $($(x)) != $(sys.$(x))
@@ -768,15 +788,12 @@
exec-prefix = $(sys.exec_prefix) ;
- compute-default-paths
- $(target-os)
- : $(sys.version)
- : $(sys.prefix)
- : $(sys.exec_prefix) ;
+ compute-default-paths $(target-os) : $(sys.version) :
+ $(sys.prefix) : $(sys.exec_prefix) ;
version = $(sys.version) ;
interpreter-cmd ?= $(cmd) ;
- cmds-to-try = ; # All done.
+ cmds-to-try = ; # All done.
}
}
else
@@ -822,13 +839,12 @@
debug-message " DLL search path:" \"$(exec-prefix:E=<empty>)\" ;
}
-
#
- # End autoconfiguration sequence
+ # End autoconfiguration sequence.
#
local target-requirements = $(condition) ;
- # Add the version, if any, to the target requirements
+ # Add the version, if any, to the target requirements.
if $(version)
{
if ! $(version) in [ feature.values python ]
@@ -840,11 +856,11 @@
target-requirements += <target-os>$(target-os) ;
- # See if we can find a framework directory on darwin
+ # See if we can find a framework directory on darwin.
local framework-directory ;
if $(target-os) = darwin
{
- # Search upward for the framework directory
+ # Search upward for the framework directory.
local framework-directory = $(libraries[-1]) ;
while $(framework-directory:D=) && $(framework-directory:D=) != Python.framework
{
@@ -864,14 +880,14 @@
local dll-path = $(libraries) ;
- # Make sure that we can find the Python DLL on windows
- if $(target-os) = windows && $(exec-prefix)
+ # Make sure that we can find the Python DLL on Windows.
+ if ( $(target-os) = windows ) && $(exec-prefix)
{
dll-path += $(exec-prefix) ;
}
#
- # prepare usage requirements
+ # Prepare usage requirements.
#
local usage-requirements = [ system-library-dependencies $(target-os) ] ;
usage-requirements += <include>$(includes) <python.interpreter>$(interpreter-cmd) ;
@@ -879,8 +895,8 @@
{
if $(target-os) = windows
{
- # in pyconfig.h, Py_DEBUG is set if _DEBUG is set. If we
- # define Py_DEBUG we'll get multiple definition warnings.
+ # In pyconfig.h, Py_DEBUG is set if _DEBUG is set. If we define
+ # Py_DEBUG we will get multiple definition warnings.
usage-requirements += <define>_DEBUG ;
}
else
@@ -888,7 +904,7 @@
usage-requirements += <define>Py_DEBUG ;
}
}
-
+
# Global, but conditional, requirements to give access to the interpreter
# for general utilities, like other toolsets, that run Python scripts.
toolset.add-requirements
@@ -899,7 +915,7 @@
#
# Declare the "python" target. This should really be called
- # python_for_embedding
+ # python_for_embedding.
#
if $(framework-directory)
@@ -915,113 +931,116 @@
{
declare-libpython-target $(version) : $(target-requirements) ;
- # This is an evil hack. On, Windows, when Python is embedded,
- # nothing seems to set up sys.path to include Python's
- # standard library
- # (http://article.gmane.org/gmane.comp.python.general/544986). The
- # evil here, aside from the workaround necessitated by
- # Python's bug, is that:
+ # This is an evil hack. On, Windows, when Python is embedded, nothing
+ # seems to set up sys.path to include Python's standard library
+ # (http://article.gmane.org/gmane.comp.python.general/544986). The evil
+ # here, aside from the workaround necessitated by Python's bug, is that:
#
- # a. we're guessing the location of the python standard
- # library from the location of pythonXX.lib
+ # a. we're guessing the location of the python standard library from the
+ # location of pythonXX.lib
#
- # b. we're hijacking the <testing.launcher> property to get
- # the environment variable set up, and the user may want to
- # use it for something else (e.g. launch the debugger).
+ # b. we're hijacking the <testing.launcher> property to get the
+ # environment variable set up, and the user may want to use it for
+ # something else (e.g. launch the debugger).
local set-PYTHONPATH ;
if $(target-os) = windows
{
- set-PYTHONPATH =
- [ common.prepend-path-variable-command PYTHONPATH : $(libraries:D)/Lib ] ;
+ set-PYTHONPATH = [ common.prepend-path-variable-command PYTHONPATH :
+ $(libraries:D)/Lib ] ;
}
alias python
:
: $(target-requirements)
:
- # why python.lib must be listed here instead of along with
- # the system libs is a mystery, but if we don't do it, on
- # cygwin, -lpythonX.Y never appears in the command line
- # (although it does on linux).
+ # Why python.lib must be listed here instead of along with the
+ # system libs is a mystery, but if we do not do it, on cygwin,
+ # -lpythonX.Y never appears in the command line (although it does on
+ # linux).
: $(usage-requirements)
<testing.launcher>$(set-PYTHONPATH)
<library-path>$(libraries) <dll-path>$(dll-path) <library>python.lib
;
}
- # On *nix, we don't want to link either Boost.Python or Python
- # extensions to libpython, because the Python interpreter itself
- # provides all those symbols. If we linked to libpython, we'd get
- # duplicate symbols. So declare two targets -- one for building
- # extensions and another for embedding
+ # On *nix, we do not want to link either Boost.Python or Python extensions
+ # to libpython, because the Python interpreter itself provides all those
+ # symbols. If we linked to libpython, we would get duplicate symbols. So
+ # declare two targets -- one for building extensions and another for
+ # embedding.
#
# Unlike most *nix systems, Mac OS X's linker does not permit undefined
- # symbols when linking a shared library. So, we still need to link
- # against the Python framework, even when building extensions.
- # Note that framework builds of Python always use shared libraries,
- # so we do not need to worry about duplicate Python symbols.
+ # symbols when linking a shared library. So, we still need to link against
+ # the Python framework, even when building extensions. Note that framework
+ # builds of Python always use shared libraries, so we do not need to worry
+ # about duplicate Python symbols.
if $(target-os) in windows cygwin darwin
{
alias python_for_extensions : python : $(target-requirements) ;
}
- # On AIX we need Python extensions and Boost.Python to import symbols
- # from the Python interpreter. Dynamic libraries opened with dlopen()
- # do not inherit the symbols from the Python interpreter.
+ # On AIX we need Python extensions and Boost.Python to import symbols from
+ # the Python interpreter. Dynamic libraries opened with dlopen() do not
+ # inherit the symbols from the Python interpreter.
else if $(target-os) = aix
{
alias python_for_extensions
- :
- : $(target-requirements)
- :
- : $(usage-requirements) <linkflags>-Wl,-bI:$(libraries[1])/python.exp
- ;
+ :
+ : $(target-requirements)
+ :
+ : $(usage-requirements) <linkflags>-Wl,-bI:$(libraries[1])/python.exp
+ ;
}
else
{
alias python_for_extensions
- :
- : $(target-requirements)
- :
- : $(usage-requirements)
- ;
+ :
+ : $(target-requirements)
+ :
+ : $(usage-requirements)
+ ;
}
}
+
rule configured ( )
{
return $(.configured) ;
}
+
type.register PYTHON_EXTENSION : : SHARED_LIB ;
+
local rule register-extension-suffix ( root : condition * )
{
local suffix ;
switch [ feature.get-values target-os : $(condition) ]
{
- case windows : suffix = pyd ;
- case cygwin : suffix = dll ;
- case hpux :
- {
- if [ feature.get-values python : $(condition) ] in 1.5 1.6 2.0 2.1 2.2 2.3 2.4
- {
- suffix = sl ;
- }
- else
- {
- suffix = so ;
- }
- }
- case * : suffix = so ;
+ case windows : suffix = pyd ;
+ case cygwin : suffix = dll ;
+ case hpux :
+ {
+ if [ feature.get-values python : $(condition) ] in 1.5 1.6 2.0 2.1 2.2 2.3 2.4
+ {
+ suffix = sl ;
+ }
+ else
+ {
+ suffix = so ;
+ }
+ }
+ case * : suffix = so ;
}
type.set-generated-target-suffix PYTHON_EXTENSION : $(condition) : <$(root).$(suffix)> ;
}
+
# Unset 'lib' prefix for PYTHON_EXTENSION
type.set-generated-target-prefix PYTHON_EXTENSION : : "" ;
+
rule python-extension ( name : sources * : requirements * : default-build * :
usage-requirements * )
{
@@ -1044,7 +1063,7 @@
IMPORT python : python-extension : : python-extension ;
-# Support for testing
+# Support for testing.
type.register PY : py ;
type.register RUN_PYD_OUTPUT ;
type.register RUN_PYD : : TEST ;
@@ -1113,38 +1132,38 @@
local extension = [ generators.construct $(project) $(name) :
PYTHON_EXTENSION : $(property-set) : $(s) $(libs) ] ;
- # The important part of usage requirements returned
- # from PYTHON_EXTENSION generator are xdll-path
- # properties that will allow us to find the python
- # extension at runtime.
+ # The important part of usage requirements returned from
+ # PYTHON_EXTENSION generator are xdll-path properties that will
+ # allow us to find the python extension at runtime.
property-set = [ $(property-set).add $(extension[1]) ] ;
- # Ignore usage requirements. We're a top-level
- # generator and nobody is going to use what we
- # generate.
+ # Ignore usage requirements. We're a top-level generator and
+ # nobody is going to use what we generate.
new-sources += $(extension[2-]) ;
}
}
property-set = [ $(property-set).add-raw <dependency>$(other-pythons) ] ;
- result = [ construct-result $(python) $(extensions) $(new-sources)
- : $(project) $(name) : $(property-set) ] ;
+ result = [ construct-result $(python) $(extensions) $(new-sources) :
+ $(project) $(name) : $(property-set) ] ;
}
}
+
generators.register
[ new python-test-generator python.capture-output : : RUN_PYD_OUTPUT ] ;
generators.register-standard testing.expect-success
: RUN_PYD_OUTPUT : RUN_PYD ;
-# There are two different ways of spelling OS names. One is used for
-# [ os.name ] and the other is used for the <host-os> and <target-os>
-# properties. Until that is remedied, this sets up a crude mapping
-# from the latter to the former, that will work *for the purposes of
-# cygwin/NT cross-builds only*. Couldn't think of a better name than
-# "translate"
+
+# There are two different ways of spelling OS names. One is used for [ os.name ]
+# and the other is used for the <host-os> and <target-os> properties. Until that
+# is remedied, this sets up a crude mapping from the latter to the former, that
+# will work *for the purposes of cygwin/NT cross-builds only*. Could not think
+# of a better name than "translate".
+#
.translate-os-windows = NT ;
.translate-os-cygwin = CYGWIN ;
local rule translate-os ( src-os )
@@ -1153,63 +1172,62 @@
return $(x[1]) ;
}
+
# Extract the path to a single ".pyd" source. This is used to build the
# PYTHONPATH for running bpl tests.
+#
local rule pyd-pythonpath ( source )
{
return [ on $(source) return $(LOCATE) $(SEARCH) ] ;
}
-# The flag settings on testing.capture-output do not
-# apply to python.capture output at the moment.
-# Redo this explicitly.
+
+# The flag settings on testing.capture-output do not apply to python.capture
+# output at the moment. Redo this explicitly.
toolset.flags python.capture-output ARGS <testing.arg> ;
+
+
rule capture-output ( target : sources * : properties * )
{
- # Setup up proper DLL search path.
- # Here, $(sources[1]) is python module and $(sources[2]) is
- # DLL. Only $(sources[1]) is passed to testing.capture-output,
- # so RUN_PATH variable on $(sources[2]) is not consulted. Move it
- # over explicitly.
+ # Setup up a proper DLL search path. Here, $(sources[1]) is a python module
+ # and $(sources[2]) is a DLL. Only $(sources[1]) is passed to
+ # testing.capture-output, so RUN_PATH variable on $(sources[2]) is not
+ # consulted. Move it over explicitly.
RUN_PATH on $(sources[1]) = [ on $(sources[2-]) return $(RUN_PATH) ] ;
PYTHONPATH = [ sequence.transform pyd-pythonpath : $(sources[2-]) ] ;
PYTHONPATH += [ feature.get-values pythonpath : $(properties) ] ;
-
- # After test is run, we remove the Python module, but not the Python
- # script.
- testing.capture-output $(target) : $(sources[1]) : $(properties)
- : $(sources[2-]) ;
-
- # PYTHONPATH is different; it will be interpreted by whichever
- # Python is invoked and so must follow path rules for the target
- # os. The only OSes where we can run pythons for other OSes
- # currently are NT and CYGWIN, so we only need to handle those
- # cases.
+
+ # After test is run, we remove the Python module, but not the Python script.
+ testing.capture-output $(target) : $(sources[1]) : $(properties) :
+ $(sources[2-]) ;
+
+ # PYTHONPATH is different; it will be interpreted by whichever Python is
+ # invoked and so must follow path rules for the target os. The only OSes
+ # where we can run python for other OSes currently are NT and CYGWIN so we
+ # only need to handle those cases.
local target-os = [ feature.get-values target-os : $(properties) ] ;
- # oddly, host-os isn't in properties, so grab the default value.
+ # Oddly, host-os is not in properties, so grab the default value.
local host-os = [ feature.defaults host-os ] ;
host-os = $(host-os:G=) ;
if $(target-os) != $(host-os)
{
- PYTHONPATH =
- [ sequence.transform $(host-os)-to-$(target-os)-path : $(PYTHONPATH) ] ;
+ PYTHONPATH = [ sequence.transform $(host-os)-to-$(target-os)-path :
+ $(PYTHONPATH) ] ;
}
- local path-separator =
- [ os.path-separator [ translate-os $(target-os) ] ] ;
- local set-PYTHONPATH =
- [ common.variable-setting-command PYTHONPATH : $(PYTHONPATH:J=$(path-separator)) ] ;
+ local path-separator = [ os.path-separator [ translate-os $(target-os) ] ] ;
+ local set-PYTHONPATH = [ common.variable-setting-command PYTHONPATH :
+ $(PYTHONPATH:J=$(path-separator)) ] ;
LAUNCHER on $(target) = $(set-PYTHONPATH) [ on $(target) return $(PYTHON) ] ;
}
+
rule bpl-test ( name : sources * : requirements * )
{
sources ?= $(name).py $(name).cpp ;
- return [ testing.make-test
- run-pyd : $(sources) /boost/python//boost_python
- : $(requirements) : $(name) ] ;
+ return [ testing.make-test run-pyd : $(sources) /boost/python//boost_python
+ : $(requirements) : $(name) ] ;
}
-IMPORT $(__name__) : bpl-test : : bpl-test ;
-
+IMPORT $(__name__) : bpl-test : : bpl-test ;
Modified: branches/release/tools/build/v2/tools/qt3.jam
==============================================================================
--- branches/release/tools/build/v2/tools/qt3.jam (original)
+++ branches/release/tools/build/v2/tools/qt3.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -2,10 +2,10 @@
# 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)
-# Support for the Qt GUI library version 3
-# (http://www.trolltech.com/products/qt3/index.html).
-# For new developments, it's recommented to use Qt4 via the qt4
-# Boost.Build module.
+# Support for the Qt GUI library version 3
+# (http://www.trolltech.com/products/qt3/index.html).
+# For new developments, it is recommended to use Qt4 via the qt4 Boost.Build
+# module.
import modules ;
import feature ;
@@ -16,15 +16,14 @@
import project ;
import toolset : flags ;
-# Convert this module into a project, so that we can declare
-# targets here.
-
+# Convert this module into a project, so that we can declare targets here.
project.initialize $(__name__) ;
project qt3 ;
-# Initialized the QT support module. The 'prefix' parameter
-# tells where QT is installed. When not given, environmental
-# variable QTDIR should be set.
+
+# Initialized the QT support module. The 'prefix' parameter tells where QT is
+# installed. When not given, environmental variable QTDIR should be set.
+#
rule init ( prefix ? )
{
if ! $(prefix)
@@ -51,23 +50,21 @@
.prefix = $(prefix) ;
generators.register-standard qt3.moc : H : CPP(moc_%) : <allow>qt3 ;
- # Note: the OBJ target type here is fake, take a look
- # at qt4.jam/uic-h-generator for explanations that
- # apply in this case as well.
+ # Note: the OBJ target type here is fake, take a look at
+ # qt4.jam/uic-h-generator for explanations that apply in this case as
+ # well.
generators.register [ new moc-h-generator-qt3
qt3.moc.cpp : MOCCABLE_CPP : OBJ : <allow>qt3 ] ;
- # The UI type is defined in types/qt.jam,
- # and UIC_H is only used in qt.jam, but not in qt4.jam, so
- # define it here.
+ # The UI type is defined in types/qt.jam, and UIC_H is only used in
+ # qt.jam, but not in qt4.jam, so define it here.
type.register UIC_H : : H ;
generators.register-standard qt3.uic-h : UI : UIC_H : <allow>qt3 ;
- # The following generator is used to convert UI files to CPP
- # It creates UIC_H from UI, and constructs CPP from UI/UIC_H
- # In addition, it also returns UIC_H target, so that it can bee
- # mocced.
+ # The following generator is used to convert UI files to CPP. It creates
+ # UIC_H from UI, and constructs CPP from UI/UIC_H. In addition, it also
+ # returns UIC_H target, so that it can be mocced.
class qt::uic-cpp-generator : generator
{
rule __init__ ( )
@@ -146,11 +143,11 @@
local r = [ virtual-target.register $(target) ] ;
- # Since this generator will return H target, the linking generator
- # won't use it at all, and won't set any dependency on it.
- # However, we need to target to be seen by bjam, so that dependency
- # from sources to this generated header is detected -- if jam does
- # not know about this target, it won't do anything.
+ # Since this generator will return a H target, the linking generator
+ # won't use it at all, and won't set any dependency on it. However,
+ # we need the target to be seen by bjam, so that the dependency from
+ # sources to this generated header is detected -- if Jam does not
+ # know about this target, it won't do anything.
DEPENDS all : [ $(r).actualize ] ;
return $(r) ;
@@ -159,25 +156,26 @@
}
-# Query the installation directory
-# This is needed in at least two scenarios
-# First, when re-using sources from the Qt-Tree.
-# Second, to "install" custom Qt plugins to the Qt-Tree.
+# Query the installation directory. This is needed in at least two scenarios.
+# First, when re-using sources from the Qt-Tree. Second, to "install" custom Qt
+# plugins to the Qt-Tree.
+#
rule directory
{
return $(.prefix) ;
}
-# -f forces moc to include the processed source file.
-# Without it, it would think that .qpp is not a header and would not
-# include it from the generated file.
+# -f forces moc to include the processed source file. Without it, it would think
+# that .qpp is not a header and would not include it from the generated file.
+#
actions moc
{
$(.prefix)/bin/moc -f $(>) -o $(<)
}
-# When moccing .cpp files, we don't need -f, otherwise generated
-# code will include .cpp and we'll get duplicated symbols.
+# When moccing .cpp files, we don't need -f, otherwise generated code will
+# include .cpp and we'll get duplicated symbols.
+#
actions moc.cpp
{
$(.prefix)/bin/moc $(>) -o $(<)
@@ -186,27 +184,26 @@
space = " " ;
-# Sometimes it's required to make 'plugins' available during
-# uic invocation. To help with this we add paths to all dependency
-# libraries to uic commane line. The intention is that it's possible
-# to write
+# Sometimes it's required to make 'plugins' available during uic invocation. To
+# help with this we add paths to all dependency libraries to uic commane line.
+# The intention is that it's possible to write
#
# exe a : ... a.ui ... : <uses>some_plugin ;
#
-# and have everything work. We'd add quite a bunch of unrelated paths
-# but it won't hurt.
+# and have everything work. We'd add quite a bunch of unrelated paths but it
+# won't hurt.
+#
flags qt3.uic-h LIBRARY_PATH <xdll-path> ;
actions uic-h
{
$(.prefix)/bin/uic $(>) -o $(<) -L$(space)$(LIBRARY_PATH)
}
+
flags qt3.uic-cpp LIBRARY_PATH <xdll-path> ;
-# The second target is uic-generated header name. It's placed in
-# build dir, but we want to include it using only basename.
+# The second target is uic-generated header name. It's placed in build dir, but
+# we want to include it using only basename.
actions uic-cpp
{
$(.prefix)/bin/uic $(>[1]) -i $(>[2]:D=) -o $(<) -L$(space)$(LIBRARY_PATH)
}
-
-
Modified: branches/release/tools/build/v2/tools/qt4.jam
==============================================================================
--- branches/release/tools/build/v2/tools/qt4.jam (original)
+++ branches/release/tools/build/v2/tools/qt4.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,4 +1,4 @@
-# Copyright 2002-2006 Vladimir Prus
+# Copyright 2002-2006 Vladimir Prus
# Copyright 2005 Alo Sarv
# Copyright 2005-2006 Juergen Hunold
#
@@ -20,12 +20,12 @@
#
# Example:
#
-# exe myapp : myapp.cpp myapp.h myapp.ui myapp.qrc
+# exe myapp : myapp.cpp myapp.h myapp.ui myapp.qrc
# /qt4//QtGui /qt4//QtNetwork ;
#
# It's also possible to run moc on cpp sources:
#
-# import cast ;
+# import cast ;
#
# exe myapp : myapp.cpp [ cast _ moccable-cpp : myapp.cpp ] /qt4//QtGui ;
#
@@ -56,11 +56,11 @@
#
# The Qt3Support library can be activated by adding
# "<qt3support>on" to requirements
-#
+#
# Use "<qt3support>on:<define>QT3_SUPPORT_WARNINGS"
# to get warnings about deprecated Qt3 support funtions and classes.
-# Files ported by the "qt3to4" conversion tool contain _tons_ of
-# warnings, so this define is not set as default.
+# Files ported by the "qt3to4" conversion tool contain _tons_ of
+# warnings, so this define is not set as default.
#
# Todo: Detect Qt3Support from Qt's configure data.
# Or add more auto-configuration (like python).
@@ -73,18 +73,61 @@
.project = [ project.current ] ;
-# Initialized the QT support module. The 'prefix' parameter
-# tells where QT is installed.
-rule init ( prefix )
+# Initialized the QT support module. The 'prefix' parameter tells where QT is
+# installed.
+#
+rule init ( prefix : full_bin ? : full_inc ? : full_lib ? )
{
project.push-current $(.project) ;
-
+
+ # pre-build paths to detect reinitializations changes
+ local inc_prefix lib_prefix bin_prefix ;
+ if $(full_inc)
+ {
+ inc_prefix = $(full_inc) ;
+ }
+ else
+ {
+ inc_prefix = $(prefix)/include ;
+ }
+ if $(full_lib)
+ {
+ lib_prefix = $(full_lib) ;
+ }
+ else
+ {
+ lib_prefix = $(prefix)/lib ;
+ }
+ if $(full_bin)
+ {
+ bin_prefix = $(full_bin) ;
+ }
+ else
+ {
+ bin_prefix = $(prefix)/bin ;
+ }
+
if $(.initialized)
{
if $(prefix) != $(.prefix)
{
errors.error
- "Attempt the reinitialize QT with different installation prefix" ;
+ "Attempt the reinitialize QT with different installation prefix" ;
+ }
+ if $(inc_prefix) != $(.incprefix)
+ {
+ errors.error
+ "Attempt the reinitialize QT with different include path" ;
+ }
+ if $(lib_prefix) != $(.libprefix)
+ {
+ errors.error
+ "Attempt the reinitialize QT with different library path" ;
+ }
+ if $(bin_prefix) != $(.binprefix)
+ {
+ errors.error
+ "Attempt the reinitialize QT with different bin path" ;
}
}
else
@@ -92,360 +135,163 @@
.initialized = true ;
.prefix = $(prefix) ;
- #~ Setup prefixes for include, binaries and libs.
- #~ TODO: Implement overrides in "init" parameter list.
+ # Setup prefixes for include, binaries and libs.
.incprefix = $(.prefix)/include ;
.libprefix = $(.prefix)/lib ;
.binprefix = $(.prefix)/bin ;
# Generates cpp files from header files using "moc" tool
generators.register-standard qt4.moc : H : CPP(moc_%) : <allow>qt4 ;
-
- # The OBJ result type is a fake, 'H' will be really produces.
- # See comments on the generator calss, defined below
- # the 'init' function.
- generators.register [ new uic-h-generator qt4.uic-h : UI : OBJ
- : <allow>qt4 ] ;
-
+
+ # The OBJ result type is a fake, 'H' will be really produced. See
+ # comments on the generator class, defined below the 'init' function.
+ generators.register [ new uic-h-generator qt4.uic-h : UI : OBJ :
+ <allow>qt4 ] ;
+
# The OBJ result type is a fake here too.
- generators.register [ new moc-h-generator
+ generators.register [ new moc-h-generator
qt4.moc.inc : MOCCABLE_CPP : OBJ : <allow>qt4 ] ;
- generators.register [ new moc-inc-generator
+ generators.register [ new moc-inc-generator
qt4.moc.inc : MOCCABLE_H : OBJ : <allow>qt4 ] ;
- # Generates .cpp file from qrc file
+ # Generates .cpp files from .qrc files.
generators.register-standard qt4.rcc : QRC : CPP(qrc_%) ;
-
- # dependency scanner for wrapped files
- type.set-scanner QRC : qrc-scanner ;
+ # dependency scanner for wrapped files.
+ type.set-scanner QRC : qrc-scanner ;
+
# Test for a buildable Qt.
if [ glob $(.prefix)/Jamroot ]
{
- # Import all Qt Modules
- local all-libraries = QtCore QtGui QtNetwork QtXml QtSql QtSvg QtOpenGL Qt3Support QtTest QtAssistantClient QtDesigner QtUiTools QtDBus QtScript ;
- for local l in $(all-libraries)
- {
- alias $(l)
- : $(.prefix)//$(l)
- :
- :
- : <allow>qt4
- ;
- explicit $(l) ;
- }
+ .bjam-qt = true
+
+ # this will declare QtCore (and qtmain on <target-os>windows)
+ add-shared-library QtCore ;
}
else
- # Use pre-built Qt
+ # Setup common pre-built Qt.
+ # Special setup for QtCore on which everything depends
{
- local usage-requirements =
- <include>$(.incprefix)
- <library-path>$(.libprefix)
- <dll-path>$(.libprefix)
- <threading>multi
- <allow>qt4
- ;
-
+ local usage-requirements =
+ <include>$(.incprefix)
+ <library-path>$(.libprefix)
+ <dll-path>$(.libprefix)
+ <threading>multi
+ <allow>qt4 ;
+
local suffix ;
if [ os.name ] = NT
{
- # On NT, the libs have "4" suffix, and "d" suffix in debug builds
- # Also, on NT we must link against qtmain library (for WinMain)
- suffix_version = "4" ;
- suffix_debug = "d" ;
- lib qtmain
+ # On NT, the libs have "4" suffix, and "d" suffix in debug
+ # builds. Also, on NT we must link against the qtmain library
+ # (for WinMain).
+ .suffix_version = "4" ;
+ .suffix_debug = "d" ;
+ lib qtmain
: # sources
: # requirements
- <name>qtmain$(suffix_debug)
+ <name>qtmain$(.suffix_debug)
<variant>debug
;
- lib qtmain
- : # sources
+ lib qtmain
+ : # sources
: # requirements
- <name>qtmain
+ <name>qtmain
;
main = qtmain ;
- }
+ }
else if [ os.name ] = MACOSX
{
# On MacOS X, both debug and release libraries are available.
- suffix_version = "" ;
- suffix_debug = "_debug" ;
+ .suffix_version = "" ;
+ .suffix_debug = "_debug" ;
}
- else
+ else
{
- # Since Qt-4.2, debug versions on unix have to be built separately
- # and therefore have no suffix.
- suffix_version = "" ;
- suffix_debug = "" ;
+ # Since Qt-4.2, debug versions on unix have to be built
+ # separately and therefore have no suffix.
+ .suffix_version = "" ;
+ .suffix_debug = "" ;
}
-
+
lib QtCore : $(main)
: # requirements
- <name>QtCore$(suffix_version)
+ <name>QtCore$(.suffix_version)
: # default-build
: # usage-requirements
<define>QT_CORE_LIB
<define>QT_NO_DEBUG
- <include>$(.incprefix)/QtCore
+ <include>$(.incprefix)/QtCore
$(usage-requirements)
;
lib QtCore : $(main)
: # requirements
- <name>QtCore$(suffix_debug)$(suffix_version)
+ <name>QtCore$(.suffix_debug)$(.suffix_version)
<variant>debug
: # default-build
: # usage-requirements
<define>QT_CORE_LIB
- <include>$(.incprefix)/QtCore
- $(usage-requirements)
- ;
-
- lib QtGui : QtCore
- : # requirements
- <name>QtGui$(suffix_version)
- : # default-build
- : # usage-requirements
- <define>QT_GUI_LIB
- <include>$(.incprefix)/QtGui
- ;
-
- lib QtGui : QtCore
- : # requirements
- <name>QtGui$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <define>QT_GUI_LIB
- <include>$(.incprefix)/QtGui
- ;
-
- lib QtNetwork : QtCore
- : # requirements
- <name>QtNetwork$(suffix_version)
- : # default-build
- : # usage-requirements
- <define>QT_NETWORK_LIB
- <include>$(.incprefix)/QtNetwork
- ;
- lib QtNetwork : QtCore
- : # requirements
- <name>QtNetwork$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <define>QT_NETWORK_LIB
- <include>$(.incprefix)/QtNetwork
- ;
-
- lib QtSql : QtCore
- : # requirements
- <name>QtSql$(suffix_version)
- : # default-build
- : # usage-requirements
- <define>QT_SQL_LIB
- <include>$(.incprefix)/QtSql
- ;
- lib QtSql : QtCore
- : # requirements
- <name>QtSql$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <define>QT_SQL_LIB
- <include>$(.incprefix)/QtSql
- ;
-
- lib QtXml : QtCore
- : # requirements
- <name>QtXml$(suffix_version)
- : # default-build
- : # usage-requirements
- <define>QT_XML_LIB
- <include>$(.incprefix)/QtXml
- ;
- lib QtXml : QtCore
- : # requirements
- <name>QtXml$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <define>QT_XML_LIB
- <include>$(.incprefix)/QtXml
- ;
-
- lib Qt3Support : QtGui QtNetwork QtXml QtSql
- : # requirements
- <name>Qt3Support$(suffix_version)
- <qt3support>on
- : # default-build
- : # usage-requirements
- <define>QT_QT3SUPPORT_LIB
- <define>QT3_SUPPORT
- <include>$(.incprefix)/Qt3Support
- ;
-
- lib Qt3Support : QtGui QtNetwork QtXml QtSql
- : # requirements
- <name>Qt3Support$(suffix_debug)$(suffix_version)
- <qt3support>on
- <variant>debug
- : # default-build
- : # usage-requirements
- <define>QT_QT3SUPPORT_LIB
- <define>QT3_SUPPORT
- <include>$(.incprefix)/Qt3Support
+ <include>$(.incprefix)/QtCore
+ $(usage-requirements)
;
+ }
- # Dummy target to enable "<qt3support>off" and "<library>/qt//Qt3Support" at the same time.
- # This enables quick switching from one to the other for test/porting purposes.
- alias Qt3Support : : <qt3support>off ;
-
- # OpenGl Support
- lib QtOpenGL : QtGui
- : # requirements
- <name>QtOpenGL$(suffix_version)
- : # default-build
- : # usage-requirements
- <define>QT_OPENGL_LIB
- <include>$(.incprefix)/QtOpenGL
- ;
- lib QtOpenGL : QtGui
- : # requirements
- <name>QtOpenGL$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <define>QT_OPENGL_LIB
- <include>$(.incprefix)/QtOpenGL
- ;
-
- # SVG-Support (Qt 4.1)
- lib QtSvg : QtXml QtOpenGL
- : # requirements
- <name>QtSvg$(suffix_version)
- : # default-build
- : # usage-requirements
- <define>QT_SVG_LIB
- <include>$(.incprefix)/QtSvg
- ;
- lib QtSvg : QtXml QtOpenGL
- : # requirements
- <name>QtSvg$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <define>QT_SVG_LIB
- <include>$(.incprefix)/QtSvg
- ;
-
- # Test-Support (Qt 4.1)
- lib QtTest : QtCore
- : # requirements
- <name>QtTest$(suffix_version)
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtTest
- ;
- lib QtTest : QtCore
- : # requirements
- <name>QtTest$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtTest
- ;
-
- # AssistantClient Support
- lib QtAssistantClient : QtGui
- : # requirements
- <name>QtAssistantClient$(suffix_version)
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtAssistant
- ;
- lib QtAssistantClient : QtGui
- : # requirements
- <name>QtAssistantClient$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtAssistant
- ;
-
- # Qt designer library
- lib QtDesigner : QtGui QtXml
- : # requirements
- <name>QtDesigner$(suffix_version)
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtDesigner
- ;
+ # Initialising the remaining libraries is canonical
+ add-shared-library QtGui : QtCore : QT_GUI_LIB ;
+ add-shared-library QtNetwork : QtCore : QT_NETWORK_LIB ;
+ add-shared-library QtSql : QtCore : QT_SQL_LIB ;
+ add-shared-library QtXml : QtCore : QT_XML_LIB ;
- lib QtDesigner : QtGui QtXml
- : # requirements
- <name>QtDesigner$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtDesigner
- ;
+ add-shared-library Qt3Support : QtGui QtNetwork QtXml QtSql
+ : QT_QT3SUPPORT_LIB QT3_SUPPORT
+ : <qt3support>on ;
- # Support for dynamic Widgets (Qt 4.1)
- lib QtUiTools : QtGui QtXml
- : # requirements
- <name>QtUiTools
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtUiTools
- ;
- lib QtUiTools : QtGui QtXml
- : # requirements
- <name>QtUiTools$(suffix_debug)
- <variant>debug
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtUiTools
- ;
+ # Dummy target to enable "<qt3support>off" and
+ # "<library>/qt//Qt3Support" at the same time. This enables quick
+ # switching from one to the other for test/porting purposes.
+ alias Qt3Support : : : : <qt3support>off ;
- # DBus-Support (Qt 4.2)
- lib QtDBus : QtXml
- : # requirements
- <name>QtDBus$(suffix_version)
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtDBus
- ;
- lib QtDBus : QtXml
- : # requirements
- <name>QtDBus$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtDBus
- ;
+ # OpenGl Support
+ add-shared-library QtOpenGL : QtGui : QT_OPENGL_LIB ;
- # Script-Engine (Qt 4.3)
- lib QtScript : QtGui QtXml
- : # requirements
- <name>QtScript$(suffix_version)
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtScript
- ;
- lib QtScript : QtGui QtXml
- : # requirements
- <name>QtScript$(suffix_debug)$(suffix_version)
- <variant>debug
- : # default-build
- : # usage-requirements
- <include>$(.incprefix)/QtScript
- ;
- }
+ # SVG-Support (Qt 4.1)
+ add-shared-library QtSvg : QtXml QtOpenGL : QT_SVG_LIB ;
+
+ # Test-Support (Qt 4.1)
+ add-shared-library QtTest : QtCore ;
+
+ # Qt designer library
+ add-shared-library QtDesigner : QtGui QtXml ;
+
+ # Support for dynamic Widgets (Qt 4.1)
+ add-static-library QtUiTools : QtGui QtXml ;
+
+ # DBus-Support (Qt 4.2)
+ add-shared-library QtDBus : QtXml ;
+
+ # Script-Engine (Qt 4.3)
+ add-shared-library QtScript : QtGui QtXml ;
+
+ # WebKit (Qt 4.4)
+ add-shared-library QtWebKit : QtGui : QT_WEBKIT_LIB ;
+
+ # Phonon Multimedia (Qt 4.4)
+ add-shared-library phonon : QtGui QtXml : QT_PHONON_LIB ;
+
+ # XmlPatterns-Engine (Qt 4.4)
+ add-shared-library QtXmlPatterns : QtNetwork : QT_XMLPATTERNS_LIB ;
+
+ # Help-Engine (Qt 4.4)
+ add-shared-library QtHelp : QtGui QtSql QtXml ;
+
+ # AssistantClient Support
+ # Compat library
+ # Pre-4.4 help system, use QtHelp for new programs
+ add-shared-library QtAssistantClient : QtGui : : : QtAssistant ;
}
-
+
project.pop-current ;
}
@@ -456,17 +302,15 @@
-# This custom generator is needed because it QT4, UI files are translated
-# only in H files, and no C++ files are created. Further, the H files
-# need not be passed via MOC. The header is used only via inclusion.
-# If we define standard UI -> H generator, Boost.Build will run
-# MOC on H, and the compile resulting cpp. It will give a warning, since
-# output from moc will be empty.
-#
-# This generator is declared with UI -> OBJ signature, so it's
-# invoked when linking generator tries to convert sources to OBJ,
-# but it produces target of type H. This is non-standard, but allowed.
-# That header won't be mocced.
+# This custom generator is needed because in QT4, UI files are translated only
+# into H files, and no C++ files are created. Further, the H files need not be
+# passed via MOC. The header is used only via inclusion. If we define a standard
+# UI -> H generator, Boost.Build will run MOC on H, and then compile the
+# resulting cpp. It will give a warning, since output from moc will be empty.
+#
+# This generator is declared with a UI -> OBJ signature, so it gets invoked when
+# linking generator tries to convert sources to OBJ, but it produces target of
+# type H. This is non-standard, but allowed. That header won't be mocced.
#
class uic-h-generator : generator
{
@@ -476,31 +320,29 @@
}
rule run ( project name ? : property-set : sources * )
- {
- if ! $(name)
+ {
+ if ! $(name)
{
name = [ $(sources[0]).name ] ;
name = $(name:B) ;
}
-
- local a = [ new action $(sources[1]) : qt4.uic-h :
- $(property-set) ] ;
-
+
+ local a = [ new action $(sources[1]) : qt4.uic-h : $(property-set) ] ;
+
# The 'ui_' prefix is to match qmake's default behavior.
- local target = [
- new file-target ui_$(name) : H : $(project) : $(a) ] ;
-
+ local target = [ new file-target ui_$(name) : H : $(project) : $(a) ] ;
+
local r = [ virtual-target.register $(target) ] ;
-
+
# Since this generator will return a H target, the linking generator
# won't use it at all, and won't set any dependency on it. However, we
# need the target to be seen by bjam, so that dependency from sources to
# this generated header is detected -- if jam does not know about this
# target, it won't do anything.
DEPENDS all : [ $(r).actualize ] ;
-
+
return $(r) ;
- }
+ }
}
@@ -512,29 +354,29 @@
}
rule run ( project name ? : property-set : sources * )
- {
+ {
if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_CPP
- {
+ {
name = [ $(sources[0]).name ] ;
name = $(name:B) ;
-
+
local a = [ new action $(sources[1]) : qt4.moc.inc :
- $(property-set) ] ;
-
- local target = [
- new file-target $(name) : MOC : $(project) : $(a) ] ;
-
+ $(property-set) ] ;
+
+ local target = [ new file-target $(name) : MOC : $(project) : $(a)
+ ] ;
+
local r = [ virtual-target.register $(target) ] ;
-
+
# Since this generator will return a H target, the linking generator
# won't use it at all, and won't set any dependency on it. However,
# we need the target to be seen by bjam, so that dependency from
# sources to this generated header is detected -- if jam does not
# know about this target, it won't do anything.
DEPENDS all : [ $(r).actualize ] ;
-
+
return $(r) ;
- }
+ }
}
}
@@ -547,82 +389,156 @@
}
rule run ( project name ? : property-set : sources * )
- {
+ {
if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_H
- {
+ {
name = [ $(sources[0]).name ] ;
name = $(name:B) ;
-
+
local a = [ new action $(sources[1]) : qt4.moc.inc :
- $(property-set) ] ;
-
- local target = [
- new file-target moc_$(name) : CPP : $(project) : $(a) ] ;
-
+ $(property-set) ] ;
+
+ local target = [ new file-target moc_$(name) : CPP : $(project) :
+ $(a) ] ;
+
# Since this generator will return a H target, the linking generator
# won't use it at all, and won't set any dependency on it. However,
# we need the target to be seen by bjam, so that dependency from
# sources to this generated header is detected -- if jam does not
# know about this target, it won't do anything.
DEPENDS all : [ $(target).actualize ] ;
-
+
return [ virtual-target.register $(target) ] ;
- }
- }
+ }
+ }
}
# Query the installation directory. This is needed in at least two scenarios.
# First, when re-using sources from the Qt-Tree. Second, to "install" custom Qt
# plugins to the Qt-Tree.
+#
rule directory
{
return $(.prefix) ;
}
+# Add a shared Qt library.
+rule add-shared-library ( lib-name : depends-on * : usage-defines * : requirements * : include ? )
+{
+ add-library $(lib-name) : $(.suffix_version) : $(depends-on) : $(usage-defines) : $(requirements) : $(include) ;
+}
+
+# Add a static Qt library.
+rule add-static-library ( lib-name : depends-on * : usage-defines * : requirements * : include ? )
+{
+ add-library $(lib-name) : : $(depends-on) : $(usage-defines) : $(requirements) : $(include) ;
+}
+
+# Add a Qt library.
+# Static libs are unversioned, whereas shared libs have the major number as suffix.
+# Creates both release and debug versions on platforms where both are enabled by Qt configure.
+# Flags:
+# - lib-name Qt library Name
+# - version Qt major number used as shared library suffix (QtCore4.so)
+# - depends-on other Qt libraries
+# - usage-defines those are set by qmake, so set them when using this library
+# - requirements addional requirements
+# - include non-canonical include path. The canonical path is $(.incprefix)/$(lib-name).
+rule add-library ( lib-name : version ? : depends-on * : usage-defines * : requirements * : include ? )
+{
+ if $(.bjam-qt)
+ {
+ # Import Qt module
+ # Eveything will be setup there
+ alias $(lib-name)
+ : $(.prefix)//$(lib-name)
+ :
+ :
+ : <allow>qt4 ;
+ }
+ else
+ {
+ local real_include ;
+ real_include ?= $(include) ;
+ real_include ?= $(lib-name) ;
+
+ lib $(lib-name)
+ : # sources
+ $(depends-on)
+ : # requirements
+ <name>$(lib-name)$(version)
+ $(requirements)
+ : # default-build
+ : # usage-requirements
+ <define>$(usage-defines)
+ <include>$(.incprefix)/$(real_include)
+ ;
+
+ lib $(lib-name)
+ : # sources
+ $(depends-on)
+ : # requirements
+ <name>$(lib-name)$(.suffix_debug)$(version)
+ $(requirements)
+ <variant>debug
+ : # default-build
+ : # usage-requirements
+ <define>$(usage-defines)
+ <include>$(.incprefix)/$(real_include)
+ ;
+ }
+
+ # Make library explicit so that a simple <use>qt4 will not bring in everything.
+ # And some components like QtDBus/Phonon may not be available on all platforms.
+ explicit $(lib-name) ;
+}
+
-# Get <include> and <defines> from current toolset
+# Get <include> and <defines> from current toolset.
flags qt4.moc INCLUDES <include> ;
flags qt4.moc DEFINES <define> ;
-# Processes headers to create Qt MetaObject information
-# Qt4-moc has its c++-parser, so pass INCLUDES and DEFINES.
+# Processes headers to create Qt MetaObject information. Qt4-moc has its
+# c++-parser, so pass INCLUDES and DEFINES.
+#
actions moc
{
$(.binprefix)/moc -I$(INCLUDES) -D$(DEFINES) -f $(>) -o $(<)
}
-# When moccing files for include only, we don't need -f,
-# otherwise the generated code will include the .cpp
-# and we'll get duplicated symbols.
+# When moccing files for include only, we don't need -f, otherwise the generated
+# code will include the .cpp and we'll get duplicated symbols.
+#
actions moc.inc
{
$(.binprefix)/moc -I$(INCLUDES) -D$(DEFINES) $(>) -o $(<)
}
-# Generates source files from resource files
+# Generates source files from resource files.
+#
actions rcc
{
$(.binprefix)/rcc $(>) -name $(>:B) -o $(<)
}
-# Generates user-interface source from .ui files
+# Generates user-interface source from .ui files.
+#
actions uic-h
{
$(.binprefix)/uic $(>) -o $(<)
}
-# Scanner for .qrc files.
-# Look for the CDATA section of the <file> tag.
-# Ignore the "alias" attribute.
-# See http://doc.trolltech.com/qt/resources.html
-# for detailed documentation of the Qt Resource System.
-class qrc-scanner : common-scanner
+# Scanner for .qrc files. Look for the CDATA section of the <file> tag. Ignore
+# the "alias" attribute. See http://doc.trolltech.com/qt/resources.html for
+# detailed documentation of the Qt Resource System.
+#
+class qrc-scanner : common-scanner
{
rule pattern ( )
{
@@ -630,5 +546,6 @@
}
}
+
# Wrapped files are "included".
scanner.register qrc-scanner : include ;
Modified: branches/release/tools/build/v2/tools/quickbook.jam
==============================================================================
--- branches/release/tools/build/v2/tools/quickbook.jam (original)
+++ branches/release/tools/build/v2/tools/quickbook.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -113,6 +113,7 @@
import project ;
import targets ;
+
# The one and only QUICKBOOK type!
type.register QUICKBOOK : qbk ;
@@ -121,15 +122,17 @@
feature.feature <quickbook-binary> : : free ;
feature.feature <quickbook-binary-dependencies> : : free dependency ;
+
# quickbook-binary-generator handles generation of the QuickBook executable, by
# marking it as a dependency for QuickBook docs.
#
# If the user supplied the QuickBook command that will be used.
#
-# Otherwise we search some sensible places for the QuickBook sources and
-# compile from scratch using the default toolset.
+# Otherwise we search some sensible places for the QuickBook sources and compile
+# from scratch using the default toolset.
#
# As a last resort we rely on the shell to find 'quickbook'.
+#
class quickbook-binary-generator : generator
{
import common modules path targets build-system ;
@@ -181,8 +184,8 @@
local quickbook-main-target = [ targets.resolve-reference $(quickbook-dir) : $(project) ] ;
# The first element are actual targets, the second are
- # properties found in target-id. We don't care about these since
- # we've passed the id ourselves.
+ # properties found in target-id. We do not care about these
+ # since we have passed the id ourselves.
quickbook-main-target =
[ $(quickbook-main-target[1]).main-target quickbook ] ;
@@ -192,10 +195,9 @@
# Ignore usage-requirements returned as first element.
quickbook-binary-dependencies = $(quickbook-binary-dependencies[2-]) ;
- # Some toolsets generate extra targets (e.g. RSP).
- # We must mark all targets as dependencies for the project, but
- # we'll only use the EXE target for quickbook-to-boostbook
- # translation.
+ # Some toolsets generate extra targets (e.g. RSP). We must mark
+ # all targets as dependencies for the project, but we will only
+ # use the EXE target for quickbook-to-boostbook translation.
for local target in $(quickbook-binary-dependencies)
{
if [ $(target).type ] = EXE
@@ -225,8 +227,8 @@
ECHO " or site-config.jam with the call" ;
ECHO " using quickbook : /path/to/quickbook ;" ;
- # As a last resort, search for 'quickbook' command in path.
- # Note that even if the 'quickbook' command is not found,
+ # As a last resort, search for 'quickbook' command in path. Note
+ # that even if the 'quickbook' command is not found,
# get-invocation-command will still return 'quickbook' and might
# generate an error while generating the virtual-target.
@@ -234,8 +236,8 @@
}
}
- # Add $(quickbook-binary-dependencies) as a dependency of the current project
- # and set it as the <quickbook-binary> feature for the
+ # Add $(quickbook-binary-dependencies) as a dependency of the current
+ # project and set it as the <quickbook-binary> feature for the
# quickbook-to-boostbook rule, below.
property-set = [ $(property-set).add-raw
<dependency>$(quickbook-binary-dependencies)
@@ -247,7 +249,9 @@
}
}
-# Define a scanner for tracking QBK include dependencies
+
+# Define a scanner for tracking QBK include dependencies.
+#
class qbk-scanner : common-scanner
{
rule pattern ( )
@@ -258,10 +262,12 @@
}
}
+
scanner.register qbk-scanner : include ;
type.set-scanner QUICKBOOK : qbk-scanner ;
+
# Initialization of toolset.
#
# Parameters:
@@ -270,8 +276,9 @@
# When command is not supplied toolset will search for QuickBook directory and
# compile the executable from source. If that fails we still search the path for
# 'quickbook'.
+#
rule init (
- command ? # path to QuickBook executable.
+ command ? # path to the QuickBook executable.
)
{
if ! $(.initialized)
@@ -281,13 +288,16 @@
}
}
+
generators.register [ new quickbook-binary-generator quickbook.quickbook-to-boostbook : QUICKBOOK : XML ] ;
+
# <quickbook-binary> shell command to run QuickBook
# <quickbook-binary-dependencies> targets to build QuickBook from sources.
-toolset.flags quickbook.quickbook-to-boostbook QB-COMMAND <quickbook-binary> ;
-toolset.flags quickbook.quickbook-to-boostbook QB-DEPENDENCIES <quickbook-binary-dependencies> ;
-toolset.flags quickbook.quickbook-to-boostbook INCLUDES <include> ;
+toolset.flags quickbook.quickbook-to-boostbook QB-COMMAND <quickbook-binary> ;
+toolset.flags quickbook.quickbook-to-boostbook QB-DEPENDENCIES <quickbook-binary-dependencies> ;
+toolset.flags quickbook.quickbook-to-boostbook INCLUDES <include> ;
+
rule quickbook-to-boostbook ( target : source : properties * )
{
@@ -296,13 +306,15 @@
DEPENDS $(target) : [ on $(target) return $(QB-DEPENDENCIES) ] ;
}
+
actions quickbook-to-boostbook
{
- "$(QB-COMMAND)" -I"$(INCLUDES)" --output-file=$(1) $(2)
+ "$(QB-COMMAND)" -I"$(INCLUDES)" --output-file="$(1)" "$(2)"
}
-# Declare a main target to convert a quickbook source into a boostbook
-# XML file.
+
+# Declare a main target to convert a quickbook source into a boostbook XML file.
+#
rule to-boostbook ( target-name : sources * : requirements * : default-build * )
{
local project = [ project.current ] ;
Modified: branches/release/tools/build/v2/tools/stage.jam
==============================================================================
--- branches/release/tools/build/v2/tools/stage.jam (original)
+++ branches/release/tools/build/v2/tools/stage.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -4,8 +4,8 @@
# 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)
-# This module defines the 'install' rule, used to copy a set of targets to a
-# single location
+# This module defines the 'install' rule, used to copy a set of targets to a
+# single location.
import targets ;
import "class" : new ;
@@ -24,8 +24,8 @@
feature.feature <install-source-root> : : free path ;
feature.feature <so-version> : : free incidental ;
-# If 'on', version symlinks for shared libraries won't be created. Affects Unix
-# builds only.
+# If 'on', version symlinks for shared libraries will not be created. Affects
+# Unix builds only.
feature.feature <install-no-version-symlinks> : on : optional incidental ;
@@ -44,26 +44,27 @@
rule __init__ ( name-and-dir : project : sources * : requirements * : default-build * )
{
- basic-target.__init__ $(name-and-dir) : $(project) : $(sources) : $(requirements)
- : $(default-build) ;
+ basic-target.__init__ $(name-and-dir) : $(project) : $(sources) :
+ $(requirements) : $(default-build) ;
}
# If <location> is not set, sets it based on the project data.
+ #
rule update-location ( property-set )
{
local loc = [ $(property-set).get <location> ] ;
if ! $(loc)
{
loc = [ path.root $(self.name) [ $(self.project).get location ] ] ;
-
property-set = [ $(property-set).add-raw $(loc:G=<location>) ] ;
}
return $(property-set) ;
}
- # Takes a target that is installed and property set which is
- # used when installing.
+ # Takes a target that is installed and a property set which is used when
+ # installing.
+ #
rule adjust-properties ( target : build-property-set )
{
local ps-raw ;
@@ -73,33 +74,31 @@
local ps = [ $(a).properties ] ;
ps-raw = [ $(ps).raw ] ;
- # Unless <hardcode-dll-paths>true is in properties, which can
- # happen only if the user has explicitly requested it, nuke all
- # <dll-path> properties
+ # Unless <hardcode-dll-paths>true is in properties, which can happen
+ # only if the user has explicitly requested it, nuke all <dll-path>
+ # properties.
if [ $(property-set).get <hardcode-dll-paths> ] != true
{
ps-raw = [ property.change $(ps-raw) : <dll-path> ] ;
}
- # If any <dll-path> properties were specified for installing,
- # add them.
+ # If any <dll-path> properties were specified for installing, add
+ # them.
local l = [ $(build-property-set).get <dll-path> ] ;
ps-raw += $(l:G=<dll-path>) ;
- # Also copy <linkflags> feature from current build
- # set, to be used for relinking.
+ # Also copy <linkflags> feature from current build set, to be used
+ # for relinking.
local l = [ $(build-property-set).get <linkflags> ] ;
ps-raw += $(l:G=<linkflags>) ;
}
# Remove the <tag> feature on original targets.
ps-raw = [ property.change $(ps-raw) : <tag> ] ;
- # And <location>. If stage target has another stage target
- # in sources, then we'll get virtual targets with <location>
- # property set.
+ # And <location>. If stage target has another stage target in sources,
+ # then we shall get virtual targets with <location> property set.
ps-raw = [ property.change $(ps-raw) : <location> ] ;
-
local d = [ $(build-property-set).get <dependency> ] ;
ps-raw += $(d:G=<dependency>) ;
@@ -110,8 +109,8 @@
ps-raw += $(ns:G=<install-no-version-symlinks>) ;
local d = [ $(build-property-set).get <install-source-root> ] ;
- # Make the path absolute: we'll use it to compute relative
- # paths and making the path absolute will help.
+ # Make the path absolute: we shall use it to compute relative paths and
+ # making the path absolute will help.
if $(d)
{
d = [ path.root $(d) [ path.pwd ] ] ;
@@ -130,8 +129,8 @@
rule construct ( name : source-targets * : property-set )
{
- source-targets = [
- targets-to-stage $(source-targets) : $(property-set) ] ;
+ source-targets = [ targets-to-stage $(source-targets) :
+ $(property-set) ] ;
property-set = [ update-location $(property-set) ] ;
@@ -139,8 +138,8 @@
if $(ename) && $(source-targets[2])
{
- errors.error
- "When <name> property is used in 'install', only one source is allowed" ;
+ errors.error "When <name> property is used in 'install', only one"
+ "source is allowed" ;
}
local result ;
@@ -148,29 +147,29 @@
{
local staged-targets ;
- local new-properties =
- [ adjust-properties $(i) : $(property-set) ] ;
+ local new-properties = [ adjust-properties $(i) :
+ $(property-set) ] ;
- # See if something special should be done when staging this
- # type. It is indicated by presense of special "staged" type
+ # See if something special should be done when staging this type. It
+ # is indicated by the presence of a special "INSTALLED_" type.
local t = [ $(i).type ] ;
if $(t) && [ type.registered INSTALLED_$(t) ]
{
if $(ename)
{
- errors.error "In 'install': <name> property specified with target that requires relinking" ;
+ errors.error "In 'install': <name> property specified with target that requires relinking." ;
}
else
{
- local targets = [ generators.construct $(self.project) $(name) :
- INSTALLED_$(t) : $(new-properties) : $(i) ] ;
+ local targets = [ generators.construct $(self.project)
+ $(name) : INSTALLED_$(t) : $(new-properties) : $(i) ] ;
staged-targets += $(targets[2-]) ;
}
}
else
{
- staged-targets = [ stage.copy-file $(self.project) $(ename)
- : $(i) : $(new-properties) ] ;
+ staged-targets = [ stage.copy-file $(self.project) $(ename) :
+ $(i) : $(new-properties) ] ;
}
if ! $(staged-targets)
@@ -187,8 +186,9 @@
return [ property-set.empty ] $(result) ;
}
- # Given the list of source targets explicitly passed to 'stage',
- # returns the list of targets which must be staged.
+ # Given the list of source targets explicitly passed to 'stage', returns the
+ # list of targets which must be staged.
+ #
rule targets-to-stage ( source-targets * : property-set )
{
local result ;
@@ -199,14 +199,14 @@
source-targets = [ collect-targets $(source-targets) ] ;
}
- # Filter the target types, if needed
+ # Filter the target types, if needed.
local included-types = [ $(property-set).get <install-type> ] ;
for local r in $(source-targets)
{
local ty = [ $(r).type ] ;
if $(ty)
{
- # Don't stage searched libs.
+ # Do not stage searched libs.
if $(ty) != SEARCHED_LIB
{
if $(included-types)
@@ -224,8 +224,8 @@
}
else if ! $(included-types)
{
- # Don't install typeless target if there's
- # explicit list of allowed types.
+ # Don't install typeless target if there is an explicit list of
+ # allowed types.
result += $(r) ;
}
}
@@ -233,7 +233,8 @@
return $(result) ;
}
- # CONSIDER: figure out why we can't use virtual-target.traverse here.
+ # CONSIDER: figure out why we can not use virtual-target.traverse here.
+ #
rule collect-targets ( targets * )
{
# Find subvariants
@@ -261,6 +262,7 @@
}
# Returns true iff 'type' is subtype of some element of 'types-to-include'.
+ #
local rule include-type ( type : types-to-include * )
{
local found ;
@@ -280,55 +282,45 @@
# Creates a copy of target 'source'. The 'properties' object should have a
# <location> property which specifies where the target must be placed.
+#
rule copy-file ( project name ? : source : properties )
{
- local targets ;
name ?= [ $(source).name ] ;
+ local relative ;
- new-a = [
- new non-scanning-action $(source) : common.copy : $(properties) ] ;
+ local new-a = [ new non-scanning-action $(source) : common.copy :
+ $(properties) ] ;
local source-root = [ $(properties).get <install-source-root> ] ;
if $(source-root)
{
- # Get the real path of the target. We probably need to strip
- # relative path from the target name at construction...
+ # Get the real path of the target. We probably need to strip relative
+ # path from the target name at construction.
local path = [ $(source).path ] ;
path = [ path.root $(name:D) $(path) ] ;
- # Make the path absolute. Otherwise, it's hard to compute relative
- # path. The 'source-root' is already absolute, see the
+ # Make the path absolute. Otherwise, it would be hard to compute the
+ # relative path. The 'source-root' is already absolute, see the
# 'adjust-properties' method above.
path = [ path.root $(path) [ path.pwd ] ] ;
relative = [ path.relative-to $(source-root) $(path) ] ;
- # Note: using $(name:D=$(relative)) might be faster
- # here, but then we need to explicitly check that
- # relative is not ".", otherwise we might get paths like
- #
- # <prefix>/boost/.
- #
- # try to create it, and mkdir will obviously fail.
- name = [ path.root $(name:D=) $(relative) ] ;
- targets = [ new file-target $(name) exact : [ $(source).type ]
- : $(project) : $(new-a) ] ;
- }
- else
- {
- targets = [ new file-target $(name:D=) exact : [ $(source).type ]
- : $(project) : $(new-a) ] ;
}
- return $(targets) ;
+ # Note: Using $(name:D=$(relative)) might be faster here, but then we would
+ # need to explicitly check that relative is not ".", otherwise we might get
+ # paths like '<prefix>/boost/.', try to create it and mkdir would obviously
+ # fail.
+ name = [ path.join $(relative) $(name:D=) ] ;
+
+ return [ new file-target $(name) exact : [ $(source).type ] : $(project) :
+ $(new-a) ] ;
}
rule symlink ( name : project : source : properties )
{
- local a = [ new action $(source) : symlink.ln :
- $(properties) ] ;
- local targets = [
- new file-target $(name) exact : [ $(source).type ] : $(project) : $(a) ] ;
-
- return $(targets) ;
+ local a = [ new action $(source) : symlink.ln : $(properties) ] ;
+ return [ new file-target $(name) exact : [ $(source).type ] : $(project) :
+ $(a) ] ;
}
@@ -336,10 +328,8 @@
{
local action = [ $(source).action ] ;
local cloned-action = [ virtual-target.clone-action $(action) : $(project) :
- "" : $(property-set) ] ;
- local result = [ $(cloned-action).targets ] ;
-
- return $(result) ;
+ "" : $(property-set) ] ;
+ return [ $(cloned-action).targets ] ;
}
@@ -347,6 +337,7 @@
# relinking to the new location.
type.register INSTALLED_EXE : : EXE ;
+
class installed-exe-generator : generator
{
import type ;
@@ -364,7 +355,7 @@
if [ $(property-set).get <os> ] in NT CYGWIN ||
[ $(property-set).get <target-os> ] in windows cygwin
{
- # Relinking is never needed on NT
+ # Relinking is never needed on NT.
return [ stage.copy-file $(project)
: $(source) : $(property-set) ] ;
}
@@ -376,6 +367,7 @@
}
}
+
generators.register [ new installed-exe-generator ] ;
@@ -383,6 +375,7 @@
# links.
type.register INSTALLED_SHARED_LIB : : SHARED_LIB ;
+
class installed-shared-lib-generator : generator
{
import type ;
@@ -401,12 +394,9 @@
if [ $(property-set).get <os> ] in NT CYGWIN ||
[ $(property-set).get <target-os> ] in windows cygwin
{
- local copied = [ stage.copy-file $(project)
- : $(source) : $(property-set) ] ;
-
- copied = [ virtual-target.register $(copied) ] ;
-
- return $(copied) ;
+ local copied = [ stage.copy-file $(project) : $(source) :
+ $(property-set) ] ;
+ return [ virtual-target.register $(copied) ] ;
}
else
{
@@ -415,8 +405,8 @@
if ! $(a)
{
# Non-derived file, just copy.
- copied = [ stage.copy-file $(project)
- : $(source) : $(property-set) ] ;
+ copied = [ stage.copy-file $(project) : $(source) :
+ $(property-set) ] ;
}
else
{
@@ -427,38 +417,38 @@
if $(current-dll-path) != $(new-dll-path)
{
# Rpath changed, need to relink.
- copied = [ stage.relink-file
- $(project) : $(source) : $(property-set) ] ;
+ copied = [ stage.relink-file $(project) : $(source) :
+ $(property-set) ] ;
}
else
{
- copied = [ stage.copy-file $(project)
- : $(source) : $(property-set) ] ;
+ copied = [ stage.copy-file $(project) : $(source) :
+ $(property-set) ] ;
}
}
copied = [ virtual-target.register $(copied) ] ;
local result = $(copied) ;
- # If the name is in the form NNN.XXX.YYY.ZZZ, where all
- # 'X', 'Y' and 'Z' are numbers, we need to create
- # NNN.XXX and NNN.XXX.YYY symbolic links.
+ # If the name is in the form NNN.XXX.YYY.ZZZ, where all 'X', 'Y' and
+ # 'Z' are numbers, we need to create NNN.XXX and NNN.XXX.YYY
+ # symbolic links.
local m = [ MATCH (.*)\\.([0123456789]+)\\.([0123456789]+)\\.([0123456789]+)$
- : [ $(copied).name ] ] ;
+ : [ $(copied).name ] ] ;
if $(m)
{
# Symlink without version at all is used to make
# -lsome_library work.
- result += [ stage.symlink $(m[1]) : $(project)
- : $(copied) : $(property-set) ] ;
+ result += [ stage.symlink $(m[1]) : $(project) : $(copied) :
+ $(property-set) ] ;
- # Symlinks of some libfoo.N and libfoo.N.M are used
- # so that library can found at runtime, if libfoo.N.M.X
- # has soname of libfoo.N. That happens when the library
- # makes some binary compatibility guarantees. If not,
- # it's possible to skip those symlinks.
+ # Symlinks of some libfoo.N and libfoo.N.M are used so that
+ # library can found at runtime, if libfoo.N.M.X has soname of
+ # libfoo.N. That happens when the library makes some binary
+ # compatibility guarantees. If not, it is possible to skip those
+ # symlinks.
local suppress =
- [ $(property-set).get <install-no-version-symlinks> ] ;
+ [ $(property-set).get <install-no-version-symlinks> ] ;
if $(suppress) != "on"
{
@@ -478,13 +468,13 @@
# Main target rule for 'install'.
+#
rule install ( name : sources * : requirements * : default-build * )
{
local project = [ project.current ] ;
# Unless the user has explicitly asked us to hardcode dll paths, add
- # <hardcode-dll-paths>false in requirements, to override default
- # value.
+ # <hardcode-dll-paths>false in requirements, to override default value.
if ! <hardcode-dll-paths>true in $(requirements)
{
requirements += <hardcode-dll-paths>false ;
@@ -493,7 +483,7 @@
if <tag> in $(requirements:G)
{
errors.user-error
- "The <tag> property is not allowed for the 'install' rule" ;
+ "The <tag> property is not allowed for the 'install' rule" ;
}
targets.main-target-alternative
@@ -504,5 +494,6 @@
] ;
}
+
IMPORT $(__name__) : install : : install ;
IMPORT $(__name__) : install : : stage ;
Modified: branches/release/tools/build/v2/tools/symlink.jam
==============================================================================
--- branches/release/tools/build/v2/tools/symlink.jam (original)
+++ branches/release/tools/build/v2/tools/symlink.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -129,10 +129,12 @@
ln -f -s '$(>:D=:R=$(PATH_TO_SOURCE))' '$(<)'
}
-# there is a way to do this; it's a dummy rule for now
+# there is a way to do this; we fall back to a copy for now
actions ln-NT
{
- echo "NT symlinks not supported yet"
+ echo "NT symlinks not supported yet, making copy"
+ del /f /q "$(<)" 2$(NULL_OUT) $(NULL_OUT)
+ copy "$(>)" "$(<)" $(NULL_OUT)
}
IMPORT $(__name__) : symlink : : symlink ;
Modified: branches/release/tools/build/v2/tools/testing.jam
==============================================================================
--- branches/release/tools/build/v2/tools/testing.jam (original)
+++ branches/release/tools/build/v2/tools/testing.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -47,6 +47,7 @@
import common ;
import sequence ;
import errors ;
+import regex ;
rule init ( )
@@ -83,6 +84,15 @@
rule make-test ( target-type : sources + : requirements * : target-name ? )
{
target-name ?= $(sources[1]:D=:S=) ;
+
+ # Having periods (".") in the target name is problematic because the
+ # typed generator will strip the suffix and use the bare name for the
+ # file targets. Even though the location-prefix averts problems most
+ # times it doesn't prevent ambiguity issues when referring to the
+ # test targets. For example when using the XML log output. So we
+ # rename the target to remove the periods, and provide an alias
+ # for users.
+ local real-name = [ regex.replace $(target-name) "[.]" "~" ] ;
local project = [ project.current ] ;
# The <location-prefix> forces the build system for generate paths in the
@@ -91,8 +101,14 @@
local t =
[ targets.create-typed-target
[ type.type-from-rule-name $(target-type) ] : $(project)
- : $(target-name) : $(sources)
- : $(requirements) <location-prefix>$(target-name).test ] ;
+ : $(real-name) : $(sources)
+ : $(requirements) <location-prefix>$(real-name).test ] ;
+
+ # The alias to the real target, per period replacement above.
+ if $(real-name) != $(target-name)
+ {
+ alias $(target-name) : $(t) ;
+ }
# Remember the test (for --dump-tests). A good way would be to collect all
# given a project. This has some technical problems: e.g. we can't call this
@@ -239,6 +255,9 @@
}
}
+ local target-name = [ $(project).get location ] // [ $(target).name ] .test ;
+ target-name = $(target-name:J=) ;
+
local r = [ $(target).requirements ] ;
# Extract values of the <test-info> feature.
local test-info = [ $(r).get <test-info> ] ;
@@ -251,6 +270,7 @@
" ;
.contents on $(.out-xml) +=
"$(nl) <test type=\"$(type)\" name=\"$(name)\">"
+ "$(nl) <target><![CDATA[$(target-name)]]></target>"
"$(nl) <info><![CDATA[$(test-info)]]></info>"
"$(nl) <source><![CDATA[$(source-files)]]></source>"
"$(nl) </test>"
Modified: branches/release/tools/build/v2/tools/vacpp.jam
==============================================================================
--- branches/release/tools/build/v2/tools/vacpp.jam (original)
+++ branches/release/tools/build/v2/tools/vacpp.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -132,5 +132,5 @@
actions updated together piecemeal vacpp.archive
{
- ar ru$(ARFLAGS:E="") "$(<)" "$(>)"
+ ar $(ARFLAGS) ru "$(<)" "$(>)"
}
Modified: branches/release/tools/build/v2/tools/xsltproc.jam
==============================================================================
--- branches/release/tools/build/v2/tools/xsltproc.jam (original)
+++ branches/release/tools/build/v2/tools/xsltproc.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,16 +1,14 @@
-# Copyright (C) 2003 Doug Gregor. Permission to copy, use, modify,
-# sell and distribute this software is granted provided this
-# copyright notice appears in all copies. This software is provided
-# "as is" without express or implied warranty, and with no claim as
-# to its suitability for any purpose.
+# Copyright (C) 2003 Doug Gregor. Permission to copy, use, modify, sell and
+# distribute this software is granted provided this copyright notice appears in
+# all copies. This software is provided "as is" without express or implied
+# warranty, and with no claim as to its suitability for any purpose.
-# This module defines rules to apply an XSLT stylesheet to an XML file
-# using the xsltproc driver, part of libxslt.
+# This module defines rules to apply an XSLT stylesheet to an XML file using the
+# xsltproc driver, part of libxslt.
#
-# Note: except for 'init', this modules does not provide any rules
-# for end users.
+# Note: except for 'init', this modules does not provide any rules for end
+# users.
-import toolset : flags ;
import feature ;
import regex ;
import sequence ;
@@ -20,60 +18,64 @@
feature.feature xsl:path : : free ;
feature.feature catalog : : free ;
+
# Initialize xsltproc support. The parameters are:
# xsltproc: The xsltproc executable
+#
rule init ( xsltproc ? )
{
- if ! $(xsltproc)
- {
- xsltproc = [ modules.peek : XSLTPROC ] ;
- }
-
- if ! $(.initialized)
- {
- $(.initialized) = true ;
- .xsltproc = $(xsltproc) ;
- }
+ if ! $(xsltproc)
+ {
+ xsltproc = [ modules.peek : XSLTPROC ] ;
+ }
+
+ if ! $(.initialized)
+ {
+ $(.initialized) = true ;
+ .xsltproc = $(xsltproc) ;
+ }
}
+
rule compute-xslt-flags ( target : properties * )
{
- local flags ;
-
- # Raw flags.
- flags += [ feature.get-values <flags> : $(properties) ] ;
-
- # Translate <xsl:param> into command line flags.
- for local param in [ feature.get-values <xsl:param> : $(properties) ]
- {
- local namevalue = [ regex.split $(param) "=" ] ;
- flags += --stringparam $(namevalue[1]) \"$(namevalue[2])\" ;
- }
- # Translate <xsl:path>
- for local path in [ feature.get-values <xsl:path> : $(properties) ]
- {
- flags += --path \"$(path:G=)\" ;
- }
-
- # Take care of implicit dependencies
- local other-deps ;
- for local dep in [ feature.get-values <implicit-dependency> : $(properties) ]
- {
- other-deps += [ $(dep:G=).creating-subvariant ] ;
- }
-
- local implicit-target-directories ;
- for local dep in [ sequence.unique $(other-deps) ]
- {
- implicit-target-directories += [ $(dep).all-target-directories ] ;
- }
-
- for local dir in $(implicit-target-directories)
- {
- flags += --path \"$(dir)\" ;
- }
+ local flags ;
+
+ # Raw flags.
+ flags += [ feature.get-values <flags> : $(properties) ] ;
+
+ # Translate <xsl:param> into command line flags.
+ for local param in [ feature.get-values <xsl:param> : $(properties) ]
+ {
+ local namevalue = [ regex.split $(param) "=" ] ;
+ flags += --stringparam $(namevalue[1]) \"$(namevalue[2])\" ;
+ }
+
+ # Translate <xsl:path>.
+ for local path in [ feature.get-values <xsl:path> : $(properties) ]
+ {
+ flags += --path \"$(path:G=)\" ;
+ }
+
+ # Take care of implicit dependencies.
+ local other-deps ;
+ for local dep in [ feature.get-values <implicit-dependency> : $(properties) ]
+ {
+ other-deps += [ $(dep:G=).creating-subvariant ] ;
+ }
+
+ local implicit-target-directories ;
+ for local dep in [ sequence.unique $(other-deps) ]
+ {
+ implicit-target-directories += [ $(dep).all-target-directories ] ;
+ }
+
+ for local dir in $(implicit-target-directories)
+ {
+ flags += --path \"$(dir)\" ;
+ }
- return $(flags) ;
+ return $(flags) ;
}
@@ -82,31 +84,35 @@
STYLESHEET on $(target) = $(stylesheet) ;
FLAGS on $(target) += [ compute-xslt-flags $(target) : $(properties) ] ;
NAME on $(target) = $(.xsltproc) ;
-
+
for local catalog in [ feature.get-values <catalog> : $(properties) ]
{
CATALOG = [ common.variable-setting-command XML_CATALOG_FILES : $(catalog) ] ;
}
-
+
$(action) $(target) : $(source) ;
}
+
rule xslt ( target : source stylesheet : properties * )
-{
+{
return [ .xsltproc $(target) : $(source) $(stylesheet) : $(properties) : : xslt-xsltproc ] ;
}
+
rule xslt-dir ( target : source stylesheet : properties * : dirname )
-{
+{
return [ .xsltproc $(target) : $(source) $(stylesheet) : $(properties) : $(dirname) : xslt-xsltproc-dir ] ;
}
-actions xslt-xsltproc
+
+actions xslt-xsltproc bind STYLESHEET
{
- $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<)" "$(STYLESHEET)" "$(>)"
+ $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<)" "$(STYLESHEET)" "$(>)"
}
-actions xslt-xsltproc-dir
+
+actions xslt-xsltproc-dir bind STYLESHEET
{
- $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<:D)/" "$(STYLESHEET)" "$(>)"
+ $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<:D)/" "$(STYLESHEET)" "$(>)"
}
Modified: branches/release/tools/build/v2/user-config.jam
==============================================================================
--- branches/release/tools/build/v2/user-config.jam (original)
+++ branches/release/tools/build/v2/user-config.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,78 +1,86 @@
-# Copyright 2003, 2005 Douglas Gregor
-# Copyright 2004 John Maddock
-# Copyright 2002, 2003, 2004, 2007 Vladimir Prus
-# 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)
+# Copyright 2003, 2005 Douglas Gregor
+# Copyright 2004 John Maddock
+# Copyright 2002, 2003, 2004, 2007 Vladimir Prus
+# 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)
-# This file is used to configure your Boost.Build installation.
-# You can modify this file in place, or you can place it it
-# permanent location so that it's not overwritten should you
-# get new version of Boost.Build. See:
+# This file is used to configure your Boost.Build installation. You can modify
+# this file in place, or you can place it in a permanent location so that it
+# does not get overwritten should you get a new version of Boost.Build. See:
#
-# http://boost.org/boost-build2/doc/html/bbv2/reference.html#bbv2.reference.init
+# http://boost.org/boost-build2/doc/html/bbv2/reference.html#bbv2.reference.init
#
-# for documentation about permanent location.
+# for documentation about possible permanent locations.
-# This file specifies which toolsets (C++ compilers), libraries,
-# and other tools are available. Often, you should be able to
-# just uncomment existing example lines and adjust them to taste.
-# The complete list of supported tools, and configuration instructions
-# can be found at:
+# This file specifies which toolsets (C++ compilers), libraries, and other
+# tools are available. Often, you should be able to just uncomment existing
+# example lines and adjust them to taste. The complete list of supported tools,
+# and configuration instructions can be found at:
#
-# http://boost.org/boost-build2/doc/html/bbv2/reference/tools.html
+# http://boost.org/boost-build2/doc/html/bbv2/reference/tools.html
#
-# This file uses Jam language syntax to describe available tools.
-# Mostly, there are 'using' lines, that contain the name of the used
-# tools, and parameters to pass to those tools -- where paremeters
-# are separated by semicolons.
-# Important syntax notes:
+# This file uses Jam language syntax to describe available tools. Mostly,
+# there are 'using' lines, that contain the name of the used tools, and
+# parameters to pass to those tools -- where paremeters are separated by
+# semicolons. Important syntax notes:
#
-# - Both ':' and ';' must be separated from other tokens by whitespace
-# - The '\' symbol is quote character, so when specifying Windows paths
-# it's recommended to use '/' instead, or use '\\'.
+# - Both ':' and ';' must be separated from other tokens by whitespace
+# - The '\' symbol is a quote character, so when specifying Windows paths you
+# should use '/' or '\\' instead.
#
-# More details about syntax can be found at:
+# More details about the syntax can be found at:
#
-# http://boost.org/boost-build2/doc/html/bbv2/advanced.html#bbv2.advanced.jam_language
+# http://boost.org/boost-build2/doc/html/bbv2/advanced.html#bbv2.advanced.jam_language
#
+# ------------------
+# GCC configuration.
+# ------------------
-# GCC configuration
+# Configure gcc (default version).
+# using gcc ;
-# Configure gcc (default version)
-# using gcc ;
+# Configure specific gcc version, giving alternative name to use.
+# using gcc : 3.2 : g++-3.2 ;
-# Configure specific gcc version, giving alternative name to use
-# using gcc : 3.2 : g++-3.2 ;
-# MSVC configuration
+# -------------------
+# MSVC configuration.
+# -------------------
-# Configure msvc (default version, searched in standard location
-# and PATH).
-# using msvc ;
+# Configure msvc (default version, searched for in standard locations and PATH).
+# using msvc ;
-# Borland configuration
-# using borland ;
+# Configure specific msvc version (searched for in standard locations and PATH).
+# using msvc : 8.0 ;
-# STLPort configuration
+# ----------------------
+# Borland configuration.
+# ----------------------
+# using borland ;
-# Configure, specifying location of STLPort headers.
-# Libraries must be either not needed, or available to
-# the compiler by default
-# using stlport : : /usr/include/stlport ;
-# Configure, specifying locatioh of both headers and libraries
-# using stlport : : /usr/include/stlport /usr/lib ;
+# ----------------------
+# STLPort configuration.
+# ----------------------
+# Configure specifying location of STLPort headers. Libraries must be either
+# not needed or available to the compiler by default.
+# using stlport : : /usr/include/stlport ;
-# QT configuration
+# Configure specifying location of both headers and libraries explicitly.
+# using stlport : : /usr/include/stlport /usr/lib ;
-# Configure, assuming QTDIR gives the installation prefix
-# using qt ;
-# Configure with explicit installation prefix
-# using qt : /usr/opt/qt ;
+# -----------------
+# QT configuration.
+# -----------------
+# Configure assuming QTDIR gives the installation prefix.
+# using qt ;
+
+# Configure with an explicit installation prefix.
+# using qt : /usr/opt/qt ;
Modified: branches/release/tools/build/v2/util/assert.jam
==============================================================================
--- branches/release/tools/build/v2/util/assert.jam (original)
+++ branches/release/tools/build/v2/util/assert.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,142 +1,336 @@
-# Copyright 2001, 2002, 2003 Dave Abrahams
-# Copyright 2006 Rene Rivera
-# Copyright 2002, 2003 Vladimir Prus
-# 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)
+# Copyright 2001, 2002, 2003 Dave Abrahams
+# Copyright 2006 Rene Rivera
+# Copyright 2002, 2003 Vladimir Prus
+# 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)
-import errors : error-skip-frames lol->list ;
+import errors ;
import modules ;
-# assert the equality of A and B
+
+################################################################################
+#
+# Private implementation details.
+#
+################################################################################
+
+# Rule added as a replacement for the regular Jam = operator but which does not
+# ignore trailing empty string elements.
+#
+local rule exact-equal-test ( lhs * : rhs * )
+{
+ local lhs_extended = $(lhs) xxx ;
+ local rhs_extended = $(rhs) xxx ;
+ if $(lhs_extended) = $(rhs_extended)
+ {
+ return true ;
+ }
+}
+
+
+# Two lists are considered set-equal if they contain the same elements, ignoring
+# duplicates and ordering.
+#
+local rule set-equal-test ( set1 * : set2 * )
+{
+ if ( $(set1) in $(set2) ) && ( $(set2) in $(set1) )
+ {
+ return true ;
+ }
+}
+
+
+################################################################################
+#
+# Public interface.
+#
+################################################################################
+
+# Assert the equality of A and B, ignoring trailing empty string elements.
+#
rule equal ( a * : b * )
{
if $(a) != $(b)
{
- error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" ;
+ errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\"
+ (ignoring trailing empty strings) ;
}
}
-# assert that EXPECTED is the result of calling RULE-NAME with the
-# given arguments
-rule result ( expected * : rule-name args * : * )
+
+# Assert that the result of calling RULE-NAME on the given arguments has a false
+# logical value (is either an empty list or all empty strings).
+#
+rule false ( rule-name args * : * )
{
local result ;
module [ CALLER_MODULE ]
{
- modules.poke assert : result
- : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+ modules.poke assert : result : [ $(1) : $(2) : $(3) : $(4) : $(5) : $(6)
+ : $(7) : $(8) : $(9) ] ;
}
- if $(result) != $(expected)
+ if $(result)
{
- error-skip-frames 3 assertion failure: "[" $(rule-name)
- [ lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ]
- "]"
- : expected: \"$(expected)\"
- : got: \"$(result)\" ;
+ errors.error-skip-frames 3 assertion failure: Expected false result from
+ "[" $(rule-name) [ errors.lol->list $(args) : $(2) : $(3) : $(4) :
+ $(5) : $(6) : $(7) : $(8) : $(9) ] "]" : Got: "[" \"$(result)\" "]" ;
}
}
-rule .set.equal ( set1 * : set2 * )
+
+# Assert that ELEMENT is present in LIST.
+#
+rule "in" ( element : list * )
{
- if ( $(set1) in $(set2) ) && ( $(set2) in $(set1) )
+ if ! $(element) in $(list)
{
- return true ;
+ errors.error-skip-frames 3 assertion failure: Expected \"$(element)\" in
+ "[" \"$(list)\" "]" ;
}
}
-# assert that EXPECTED is equal to the result of calling RULE-NAME with the
-# given arguments
-rule result-equal ( expected * : rule-name args * : * )
+
+# Assert the inequality of A and B, ignoring trailing empty string elements.
+#
+rule not-equal ( a * : b * )
{
- local result ;
- module [ CALLER_MODULE ]
+ if $(a) = $(b)
{
- modules.poke assert : result
- : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+ errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\"
+ (ignoring trailing empty strings) ;
}
+}
- if ! [ .set.equal $(result) : $(expected) ]
+
+# Assert that ELEMENT is not present in LIST.
+#
+rule not-in ( element : list * )
+{
+ if $(element) in $(list)
{
- error-skip-frames 3 assertion failure: "[" $(rule-name)
- [ lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ]
- "]"
- : expected: \"$(expected)\"
- : got: \"$(result)\" ;
+ errors.error-skip-frames 3 assertion failure: Did not expect
+ \"$(element)\" in "[" \"$(list)\" "]" ;
}
}
-# assert that the given variable is nonempty.
-rule nonempty-variable ( name )
+
+# Assert the inequality of A and B as sets.
+#
+rule not-set-equal ( a * : b * )
{
- local value = [ modules.peek [ CALLER_MODULE ] : $(name) ] ;
+ if [ set-equal-test $(a) : $(b) ]
+ {
+ errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]"
+ and "[" \"$(b)\" "]" to not be equal as sets ;
+ }
+}
- if ! $(value)-is-nonempty
+
+# Assert that A and B are not exactly equal, not ignoring trailing empty string
+# elements.
+#
+rule not-exact-equal ( a * : b * )
+{
+ if [ exact-equal-test $(a) : $(b) ]
{
- error-skip-frames 3 assertion failure: expecting non-empty variable $(variable) ;
+ errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" ;
}
}
-# assert that the result of calling RULE-NAME on the given arguments
-# has a true logical value (is neither an empty list nor all empty
-# strings).
-rule true ( rule-name args * : * )
+
+# Assert that EXPECTED is the result of calling RULE-NAME with the given
+# arguments.
+#
+rule result ( expected * : rule-name args * : * )
{
local result ;
module [ CALLER_MODULE ]
{
- modules.poke assert : result
- : [ $(1) : $(2) : $(3) : $(4)
- : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+ modules.poke assert : result : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7)
+ : $(8) : $(9) ] ;
}
- if ! $(result)
+ if ! [ exact-equal-test $(result) : $(expected) ]
{
- error-skip-frames 3 assertion failure: expecting true result from
- "[" $(rule-name)
- [ lol->list $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ]
- "]" ;
+ errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [
+ errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) :
+ $(9) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "["
+ \"$(result)\" "]" ;
}
}
-# assert that the result of calling RULE-NAME on the given arguments
-# has a false logical value (is either an empty list or all empty
-# strings).
-rule false ( rule-name args * : * )
+
+# Assert that EXPECTED is set-equal (i.e. duplicates and ordering are ignored)
+# to the result of calling RULE-NAME with the given arguments. Note that rules
+# called this way may accept at most 8 parameters.
+#
+rule result-set-equal ( expected * : rule-name args * : * )
{
local result ;
module [ CALLER_MODULE ]
{
- modules.poke assert : result
- : [ $(1) : $(2) : $(3) : $(4)
- : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+ modules.poke assert : result : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7)
+ : $(8) : $(9) ] ;
}
- if $(result)
+ if ! [ set-equal-test $(result) : $(expected) ]
{
- error-skip-frames 3 assertion failure: expecting false result from
- "[" $(rule-name)
- [ lol->list $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ]
- "]" : got [ lol->list $(result) ] instead ;
+ errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [
+ errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) :
+ $(9) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "["
+ \"$(result)\" "]" ;
}
}
-# assert that 'element' is present in 'list'.
-rule "in" ( element : list * )
+
+# Assert the equality of A and B as sets.
+#
+rule set-equal ( a * : b * )
{
- if ! $(element) in $(list)
+ if ! [ set-equal-test $(a) : $(b) ]
{
- error-skip-frames 3 assertion failure: expecting $(element) in
- "[" $(list) "]" ;
+ errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]"
+ and "[" \"$(b)\" "]" to be equal as sets ;
}
}
-# assert that 'element' is not present in 'list'.
-rule not-in ( element : list * )
+
+# Assert that the result of calling RULE-NAME on the given arguments has a true
+# logical value (is neither an empty list nor all empty strings).
+#
+rule true ( rule-name args * : * )
{
- if $(element) in $(list)
+ local result ;
+ module [ CALLER_MODULE ]
{
- error-skip-frames 3 assertion failure: did not expect $(element) in
- "[" $(list) "]" ;
+ modules.poke assert : result : [ $(1) : $(2) : $(3) : $(4) : $(5) : $(6)
+ : $(7) : $(8) : $(9) ] ;
}
+
+ if ! $(result)
+ {
+ errors.error-skip-frames 3 assertion failure: Expected true result from
+ "[" $(rule-name) [ errors.lol->list $(args) : $(2) : $(3) : $(4) :
+ $(5) : $(6) : $(7) : $(8) : $(9) ] "]" ;
+ }
+}
+
+
+# Assert the exact equality of A and B, not ignoring trailing empty string
+# elements.
+#
+rule exact-equal ( a * : b * )
+{
+ if ! [ exact-equal-test $(a) : $(b) ]
+ {
+ errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\" ;
+ }
+}
+
+
+# Assert that the given variable is not an empty list.
+#
+rule variable-not-empty ( name )
+{
+ local value = [ modules.peek [ CALLER_MODULE ] : $(name) ] ;
+ if ! $(value)-is-not-empty
+ {
+ errors.error-skip-frames 3 assertion failure: Expected variable
+ \"$(name)\" not to be an empty list ;
+ }
+}
+
+
+rule __test__ ( )
+{
+ # Helper rule used to avoid test duplication related to different list
+ # equality test rules.
+ #
+ local rule run-equality-test ( equality-assert : ignore-trailing-empty-strings ? )
+ {
+ local not-equality-assert = not-$(equality-assert) ;
+
+ # When the given equality test is expected to ignore trailing empty
+ # strings some of the test results should be inverted.
+ local not-equality-assert-i = not-$(equality-assert) ;
+ if $(ignore-trailing-empty-strings)
+ {
+ not-equality-assert-i = $(equality-assert) ;
+ }
+
+ $(equality-assert) : ;
+ $(equality-assert) "" "" : "" "" ;
+ $(not-equality-assert-i) : "" "" ;
+ $(equality-assert) x : x ;
+ $(not-equality-assert) : x ;
+ $(not-equality-assert) "" : x ;
+ $(not-equality-assert) "" "" : x ;
+ $(not-equality-assert-i) x : x "" ;
+ $(equality-assert) x "" : x "" ;
+ $(not-equality-assert) x : "" x ;
+ $(equality-assert) "" x : "" x ;
+
+ $(equality-assert) 1 2 3 : 1 2 3 ;
+ $(not-equality-assert) 1 2 3 : 3 2 1 ;
+ $(not-equality-assert) 1 2 3 : 1 5 3 ;
+ $(not-equality-assert) 1 2 3 : 1 "" 3 ;
+ $(not-equality-assert) 1 2 3 : 1 1 2 3 ;
+ $(not-equality-assert) 1 2 3 : 1 2 2 3 ;
+ $(not-equality-assert) 1 2 3 : 5 6 7 ;
+
+ # Extra variables used here just to make sure Boost Jam or Boost Build
+ # do not handle lists with empty strings differently depending on
+ # whether they are literals or stored in variables.
+
+ local empty = ;
+ local empty-strings = "" "" ;
+ local x-empty-strings = x "" "" ;
+ local empty-strings-x = "" "" x ;
+
+ $(equality-assert) : $(empty) ;
+ $(not-equality-assert-i) "" : $(empty) ;
+ $(not-equality-assert-i) "" "" : $(empty) ;
+ $(not-equality-assert-i) : $(empty-strings) ;
+ $(not-equality-assert-i) "" : $(empty-strings) ;
+ $(equality-assert) "" "" : $(empty-strings) ;
+ $(equality-assert) $(empty) : $(empty) ;
+ $(equality-assert) $(empty-strings) : $(empty-strings) ;
+ $(not-equality-assert-i) $(empty) : $(empty-strings) ;
+ $(equality-assert) $(x-empty-strings) : $(x-empty-strings) ;
+ $(equality-assert) $(empty-strings-x) : $(empty-strings-x) ;
+ $(not-equality-assert) $(empty-strings-x) : $(x-empty-strings) ;
+ $(not-equality-assert-i) x : $(x-empty-strings) ;
+ $(not-equality-assert) x : $(empty-strings-x) ;
+ $(not-equality-assert-i) x : $(x-empty-strings) ;
+ $(not-equality-assert-i) x "" : $(x-empty-strings) ;
+ $(equality-assert) x "" "" : $(x-empty-strings) ;
+ $(not-equality-assert) x : $(empty-strings-x) ;
+ $(not-equality-assert) "" x : $(empty-strings-x) ;
+ $(equality-assert) "" "" x : $(empty-strings-x) ;
+ }
+
+
+ # ---------------
+ # Equality tests.
+ # ---------------
+
+ run-equality-test equal : ignore-trailing-empty-strings ;
+ run-equality-test exact-equal ;
+
+
+ # -------------------------
+ # assert.set-equal() tests.
+ # -------------------------
+
+ set-equal : ;
+ not-set-equal "" "" : ;
+ set-equal "" "" : "" ;
+ set-equal "" "" : "" "" ;
+ set-equal a b c : a b c ;
+ set-equal a b c : b c a ;
+ set-equal a b c a : a b c ;
+ set-equal a b c : a b c a ;
+ not-set-equal a b c : a b c d ;
+ not-set-equal a b c d : a b c ;
}
Modified: branches/release/tools/build/v2/util/container.jam
==============================================================================
--- branches/release/tools/build/v2/util/container.jam (original)
+++ branches/release/tools/build/v2/util/container.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,33 +1,31 @@
-# Copyright 2003 Dave Abrahams
-# Copyright 2002, 2003 Rene Rivera
-# Copyright 2002, 2003, 2004 Vladimir Prus
-# 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)
+# Copyright 2003 Dave Abrahams
+# Copyright 2002, 2003 Rene Rivera
+# Copyright 2002, 2003, 2004 Vladimir Prus
+# 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)
# Various container classes.
-import "class" : * ;
-
-# Base for container objects. This lets us construct recursive structures.
-# That is containers with containers in them, specifically so we can tell
-# literal values from node values.
+# Base for container objects. This lets us construct recursive structures. That
+# is containers with containers in them, specifically so we can tell literal
+# values from node values.
#
-class node
+class node
{
rule __init__ (
- value ? # Optional value to set node to initially.
+ value ? # Optional value to set node to initially.
)
{
self.value = $(value) ;
}
-
+
# Set the value of this node, passing nothing will clear it.
#
rule set ( value * )
{
self.value = $(value) ;
}
-
+
# Get the value of this node.
#
rule get ( )
@@ -37,49 +35,49 @@
}
-# A simple vector. Interface mimics the C++ std::vector and std::list,
-# with the exception that indices are one (1) based to follow Jam standard.
+# A simple vector. Interface mimics the C++ std::vector and std::list, with the
+# exception that indices are one (1) based to follow Jam standard.
#
# TODO: Possibly add assertion checks.
#
-class vector : node
+class vector : node
{
- import numbers : range ;
+ import numbers ;
import utility ;
import sequence ;
-
+
rule __init__ (
- values * # Initial contents of vector.
+ values * # Initial contents of vector.
)
{
node.__init__ ;
self.value = $(values) ;
- }
-
+ }
+
# Get the value of the first element.
#
rule front ( )
{
return $(self.value[1]) ;
}
-
+
# Get the value of the last element.
#
rule back ( )
{
return $(self.value[-1]) ;
}
-
- # Get the value of the element at the given index, one based.
- # Access to elements of recursive structures is supported directly.
- # Specifying additional index values recursively accesses the elements as
- # containers. For example: [ $(v).at 1 : 2 ] would retrieve the second element
- # of our first element. This assuming the first element is a container.
+
+ # Get the value of the element at the given index, one based. Access to
+ # elements of recursive structures is supported directly. Specifying
+ # additional index values recursively accesses the elements as containers.
+ # For example: [ $(v).at 1 : 2 ] would retrieve the second element of our
+ # first element, assuming the first element is a container.
#
rule at (
- index # The element index, one based.
- : * # Additional indices to access recursively.
- )
+ index # The element index, one based.
+ : * # Additional indices to access recursively.
+ )
{
local r = $(self.value[$(index)]) ;
if $(2)
@@ -88,15 +86,15 @@
}
return $(r) ;
}
-
+
# Get the value contained in the given element. This has the same
- # functionality and interface as "at" but in addition gets the value
- # of the referenced element, assuming it's a "node".
+ # functionality and interface as "at" but in addition gets the value of the
+ # referenced element, assuming it is a "node".
#
rule get-at (
- index # The element index, one based.
- : * # Additional indices to access recursively.
- )
+ index # The element index, one based.
+ : * # Additional indices to access recursively.
+ )
{
local r = $(self.value[$(index)]) ;
if $(2)
@@ -105,64 +103,68 @@
}
return [ $(r).get ] ;
}
-
- # Insert the given value into the front of the vector pushing the
- # rest of the elements back.
+
+ # Insert the given value into the front of the vector pushing the rest of
+ # the elements back.
#
rule push-front (
- value # Value to become first element.
- )
+ value # Value to become first element.
+ )
{
self.value = $(value) $(self.value) ;
}
-
- # Remove the front element from the vector. Does not return the value.
- # No effect if vector is empty.
+
+ # Remove the front element from the vector. Does not return the value. No
+ # effect if vector is empty.
#
rule pop-front ( )
{
self.value = $(self.value[2-]) ;
}
-
+
# Add the given value at the end of the vector.
#
rule push-back (
- value # Value to become back element.
- )
+ value # Value to become back element.
+ )
{
self.value += $(value) ;
}
-
- # Remove the back element from the vector. Does not return the value.
- # No effect if vector is empty.
+
+ # Remove the back element from the vector. Does not return the value. No
+ # effect if vector is empty.
#
rule pop-back ( )
{
self.value = $(self.value[1--2]) ;
}
-
- # Insert the given value at the given index, one based. The values
- # at and to the right of the of the index are push back to make room
- # for the new value.
+
+ # Insert the given value at the given index, one based. The values at and to
+ # the right of the index are pushed back to make room for the new value.
+ # If the index is passed the end of the vector the element is added to the
+ # end.
#
rule insert (
- index # The index to insert at, one based.
- : value # The value to insert.
- )
+ index # The index to insert at, one based.
+ : value # The value to insert.
+ )
{
local left = $(self.value[1-$(index)]) ;
- left = $(left[1--2]) ;
local right = $(self.value[$(index)-]) ;
+ if $(right)-is-not-empty
+ {
+ left = $(left[1--2]) ;
+ }
self.value = $(left) $(value) $(right) ;
}
-
- # Remove one or more elements from the vector. The range is inclusive,
- # and not specifying an end is equivalent to the [start,start] range.
+
+ # Remove one or more elements from the vector. The range is inclusive, and
+ # not specifying an end is equivalent to the [start, start] range.
#
rule erase (
- start # Index of first element ro remove.
- end ? # Optional, index of last element to remove.
- )
+ start # Index of first element to remove.
+ end ? # Optional, index of last element to remove.
+ )
{
end ?= $(start) ;
local left = $(self.value[1-$(start)]) ;
@@ -171,144 +173,167 @@
right = $(right[2-]) ;
self.value = $(left) $(right) ;
}
-
+
# Remove all elements from the vector.
#
rule clear ( )
{
self.value = ;
}
-
+
# The number of elements in the vector.
#
rule size ( )
{
return [ sequence.length $(self.value) ] ;
}
-
- # Returns "true" if there are NO elements in the vector, empty
- # otherwise.
+
+ # Returns "true" if there are NO elements in the vector, empty otherwise.
#
rule empty ( )
{
- if ! $(self.value)
+ if ! $(self.value)-is-not-empty
{
return true ;
}
}
- # Returns the list of all valid indices for this vector.
- rule indices ( )
- {
- if ! [ empty ]
- {
- local size = [ size ] ;
- return [ range 1 : $(size) ] $(size) ;
- }
- }
-
# Returns the textual representation of content.
+ #
rule str ( )
{
return "[" [ sequence.transform utility.str : $(self.value) ] "]" ;
}
- # Sorts the vector inplace, calling 'utility.less' for
- # comparisons.
- # NOTE: this rule is unused at the moment.
+ # Sorts the vector inplace, calling 'utility.less' for comparisons.
+ #
rule sort ( )
{
- self.value =
- [ sequence.insertion-sort $(self.value) : utility.less ] ;
+ self.value = [ sequence.insertion-sort $(self.value) : utility.less ] ;
}
- # Returns true if content is equal to the content of other vector.
- # Uses 'utility.equal' for comparison.
+ # Returns true if content is equal to the content of other vector. Uses
+ # 'utility.equal' for comparison.
+ #
rule equal ( another )
- {
+ {
local mismatch ;
- if [ size ] = [ $(another).size ]
+ local size = [ size ] ;
+ if $(size) = [ $(another).size ]
{
- for local i in [ indices ]
+ for local i in [ numbers.range 1 $(size) ]
{
if ! [ utility.equal [ at $(i) ] [ $(another).at $(i) ] ]
{
mismatch = true ;
}
}
- }
+ }
else
{
mismatch = true ;
}
-
- if ! $(mismatch)
+
+ if ! $(mismatch)
{
return true ;
}
}
}
-local rule __test__ ( )
+
+rule __test__ ( )
{
import assert ;
import "class" : new ;
-
- local l = [ new vector ] ;
- assert.result 0 : $(l).size ;
- assert.result : $(l).indices ;
- assert.result "[" "]" : $(l).str ;
- $(l).push-back b ;
- $(l).push-front a ;
- assert.result 1 2 : $(l).indices ;
- assert.result "[" a b "]" : $(l).str ;
- assert.result a : $(l).front ;
- assert.result b : $(l).back ;
- $(l).insert 2 : d ;
- $(l).insert 2 : c ;
- $(l).insert 4 : f ;
- $(l).insert 4 : e ;
- $(l).pop-back ;
- assert.result 5 : $(l).size ;
- assert.result d : $(l).at 3 ;
- $(l).pop-front ;
- assert.result c : $(l).front ;
- assert.false $(l).empty ;
- $(l).erase 3 4 ;
- assert.result 2 : $(l).size ;
-
- local l2 = [ new vector q w e r t y ] ;
- assert.result 6 : $(l2).size ;
- $(l).push-back $(l2) ;
- assert.result 3 : $(l).size ;
- local l2-alias = [ $(l).back ] ;
- assert.result e : $(l2-alias).at 3 ;
- $(l).clear ;
- assert.true $(l).empty ;
- assert.false $(l2-alias).empty ;
- $(l2).pop-back ;
- assert.result t : $(l2-alias).back ;
-
- local l3 = [ new vector ] ;
- $(l3).push-back [ new vector 1 2 3 4 5 ] ;
- $(l3).push-back [ new vector a b c ] ;
- assert.result "[" "[" 1 2 3 4 5 "]" "[" a b c "]" "]" : $(l3).str ;
- $(l3).push-back [ new vector [ new vector x y z ] [ new vector 7 8 9 ] ] ;
- assert.result 1 : $(l3).at 1 : 1 ;
- assert.result b : $(l3).at 2 : 2 ;
- assert.result a b c : $(l3).get-at 2 ;
- assert.result 7 8 9 : $(l3).get-at 3 : 2 ;
-
- local l4 = [ new vector 4 3 6 ] ;
- $(l4).sort ;
- assert.result 3 4 6 : $(l4).get ;
-
- assert.false $(l4).equal $(l3) ;
- local l5 = [ new vector 3 4 6 ] ;
- assert.true $(l4).equal $(l5) ;
- # Check that vectors of different sizes are considered non-equal
- $(l5).pop-back ;
- assert.false $(l4).equal $(l5) ;
- local l6 = [ new vector [ new vector 1 2 3 ] ] ;
- assert.true $(l6).equal [ new vector [ new vector 1 2 3 ] ] ;
+
+ local v1 = [ new vector ] ;
+ assert.true $(v1).equal $(v1) ;
+ assert.true $(v1).empty ;
+ assert.result 0 : $(v1).size ;
+ assert.result "[" "]" : $(v1).str ;
+ $(v1).push-back b ;
+ $(v1).push-front a ;
+ assert.result "[" a b "]" : $(v1).str ;
+ assert.result a : $(v1).front ;
+ assert.result b : $(v1).back ;
+ $(v1).insert 2 : d ;
+ $(v1).insert 2 : c ;
+ $(v1).insert 4 : f ;
+ $(v1).insert 4 : e ;
+ $(v1).pop-back ;
+ assert.result 5 : $(v1).size ;
+ assert.result d : $(v1).at 3 ;
+ $(v1).pop-front ;
+ assert.result c : $(v1).front ;
+ assert.false $(v1).empty ;
+ $(v1).erase 3 4 ;
+ assert.result 2 : $(v1).size ;
+
+ local v2 = [ new vector q w e r t y ] ;
+ assert.result 6 : $(v2).size ;
+ $(v1).push-back $(v2) ;
+ assert.result 3 : $(v1).size ;
+ local v2-alias = [ $(v1).back ] ;
+ assert.result e : $(v2-alias).at 3 ;
+ $(v1).clear ;
+ assert.true $(v1).empty ;
+ assert.false $(v2-alias).empty ;
+ $(v2).pop-back ;
+ assert.result t : $(v2-alias).back ;
+
+ local v3 = [ new vector ] ;
+ $(v3).push-back [ new vector 1 2 3 4 5 ] ;
+ $(v3).push-back [ new vector a b c ] ;
+ assert.result "[" "[" 1 2 3 4 5 "]" "[" a b c "]" "]" : $(v3).str ;
+ $(v3).push-back [ new vector [ new vector x y z ] [ new vector 7 8 9 ] ] ;
+ assert.result 1 : $(v3).at 1 : 1 ;
+ assert.result b : $(v3).at 2 : 2 ;
+ assert.result a b c : $(v3).get-at 2 ;
+ assert.result 7 8 9 : $(v3).get-at 3 : 2 ;
+
+ local v4 = [ new vector 4 3 6 ] ;
+ $(v4).sort ;
+ assert.result 3 4 6 : $(v4).get ;
+ assert.false $(v4).equal $(v3) ;
+
+ local v5 = [ new vector 3 4 6 ] ;
+ assert.true $(v4).equal $(v5) ;
+ # Check that vectors of different sizes are considered non-equal.
+ $(v5).pop-back ;
+ assert.false $(v4).equal $(v5) ;
+
+ local v6 = [ new vector [ new vector 1 2 3 ] ] ;
+ assert.true $(v6).equal [ new vector [ new vector 1 2 3 ] ] ;
+
+ local v7 = [ new vector 111 222 333 ] ;
+ assert.true $(v7).equal $(v7) ;
+ $(v7).insert 4 : 444 ;
+ assert.result 111 222 333 444 : $(v7).get ;
+ $(v7).insert 999 : xxx ;
+ assert.result 111 222 333 444 xxx : $(v7).get ;
+
+ local v8 = [ new vector "" "" "" ] ;
+ assert.true $(v8).equal $(v8) ;
+ assert.false $(v8).empty ;
+ assert.result 3 : $(v8).size ;
+ assert.result "" : $(v8).at 1 ;
+ assert.result "" : $(v8).at 2 ;
+ assert.result "" : $(v8).at 3 ;
+ assert.result : $(v8).at 4 ;
+ $(v8).insert 2 : 222 ;
+ assert.result 4 : $(v8).size ;
+ assert.result "" 222 "" "" : $(v8).get ;
+ $(v8).insert 999 : "" ;
+ assert.result 5 : $(v8).size ;
+ assert.result "" 222 "" "" "" : $(v8).get ;
+ $(v8).insert 999 : xxx ;
+ assert.result 6 : $(v8).size ;
+ assert.result "" 222 "" "" "" xxx : $(v8).get ;
+
+ # Regression test for a bug causing vector.equal to compare only the first
+ # and the last element in the given vectors.
+ local v9 = [ new vector 111 xxx 222 ] ;
+ local v10 = [ new vector 111 yyy 222 ] ;
+ assert.false $(v9).equal $(v10) ;
}
Modified: branches/release/tools/build/v2/util/doc.jam
==============================================================================
--- branches/release/tools/build/v2/util/doc.jam (original)
+++ branches/release/tools/build/v2/util/doc.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -17,6 +17,7 @@
import sequence ;
import path ;
+
# The type of output to generate.
# "console" is formated text echoed to the console (the default);
# "text" is formated text appended to the output file;
@@ -24,9 +25,10 @@
#
help-output = console ;
-# The file to output documentation to when generating "text" or "html"
-# help. This is without extension as the extension is determined by the
-# type of output.
+
+# The file to output documentation to when generating "text" or "html" help.
+# This is without extension as the extension is determined by the type of
+# output.
#
help-output-file = help ;
@@ -39,45 +41,43 @@
#
.option.detailed ?= ;
-# Generate debug output as the help is generated and modules
-# are parsed.
+# Generate debug output as the help is generated and modules are parsed.
#
.option.debug ?= ;
# Enable or disable a documentation option.
#
local rule set-option (
- option # The option name.
- : value ? # Enabled (non-empty), or disabled (empty)
- )
+ option # The option name.
+ : value ? # Enabled (non-empty), or disabled (empty)
+)
{
.option.$(option) = $(value) ;
}
+
# Set the type of output.
#
-local rule set-output (
- type
- )
+local rule set-output ( type )
{
help-output = $(type) ;
}
+
# Set the output to a file.
#
-local rule set-output-file (
- file
- )
+local rule set-output-file ( file )
{
help-output-file = $(file) ;
}
-# Extracts the brief comment from a complete comment. The brief
-# comment is the first sentence.
+
+# Extracts the brief comment from a complete comment. The brief comment is the
+# first sentence.
#
local rule brief-comment (
- docs * # The comment documentation.
- )
+ docs * # The comment documentation.
+)
{
local d = $(docs:J=" ") ;
local p = [ MATCH ".*([.])$" : $(d) ] ;
@@ -93,12 +93,13 @@
return $(brief:J="") ;
}
+
# Specifies the documentation for the current module.
#
local rule set-module-doc (
- module-name ? # The name of the module to document.
- : docs * # The documentation for the module.
- )
+ module-name ? # The name of the module to document.
+ : docs * # The documentation for the module.
+)
{
module-name ?= * ;
@@ -111,12 +112,13 @@
}
}
+
# Specifies the documentation for the current module.
#
local rule set-module-copyright (
- module-name ? # The name of the module to document.
- : copyright * # The copyright for the module.
- )
+ module-name ? # The name of the module to document.
+ : copyright * # The copyright for the module.
+)
{
module-name ?= * ;
@@ -129,15 +131,16 @@
}
}
-# Specifies the documentation for a rule in the current module.
-# If called in the global module, this documents a global rule.
+
+# Specifies the documentation for a rule in the current module. If called in the
+# global module, this documents a global rule.
#
local rule set-rule-doc (
- name # The name of the rule.
- module-name ? # The name of the module to document.
- is-local ? # Whether the rule is local to the module.
- : docs * # The documentation for the rule.
- )
+ name # The name of the rule.
+ module-name ? # The name of the module to document.
+ is-local ? # Whether the rule is local to the module.
+ : docs * # The documentation for the rule.
+)
{
module-name ?= * ;
@@ -151,13 +154,14 @@
}
}
+
# Specify a class, will turn a rule into a class.
#
local rule set-class-doc (
- name # The name of the class.
- module-name ? # The name of the module to document.
- : super-name ? # The super class name.
- )
+ name # The name of the class.
+ module-name ? # The name of the module to document.
+ : super-name ? # The super class name.
+)
{
module-name ?= * ;
@@ -174,28 +178,30 @@
$(name) $($(module-name).$(name).class-rules) ] ;
}
+
# Set the argument call signature of a rule.
#
local rule set-rule-arguments-signature (
- name # The name of the rule.
- module-name ? # The name of the module to document.
- : signature * # The arguments signature.
- )
+ name # The name of the rule.
+ module-name ? # The name of the module to document.
+ : signature * # The arguments signature.
+)
{
module-name ?= * ;
$(module-name).$(name).signature = $(signature) ;
}
+
# Specifies the documentation for an argument of a rule.
#
local rule set-argument-doc (
- name # The name of the argument.
- qualifier # Argument syntax qualifier, "*", "+", etc.
- rule-name # The name of the rule.
- module-name ? # THe optional name of the module.
- : docs * # The documentation.
- )
+ name # The name of the argument.
+ qualifier # Argument syntax qualifier, "*", "+", etc.
+ rule-name # The name of the rule.
+ module-name ? # THe optional name of the module.
+ : docs * # The documentation.
+)
{
module-name ?= * ;
@@ -208,16 +214,17 @@
}
}
-# Specifies the documentation for a variable in the current module.
-# If called in the global module, the global variable is documented.
+
+# Specifies the documentation for a variable in the current module. If called in
+# the global module, the global variable is documented.
#
local rule set-variable-doc (
- name # The name of the variable.
- default # The default value.
- initial # The initial value.
- module-name ? # The name of the module to document.
- : docs * # The documentation for the variable.
- )
+ name # The name of the variable.
+ default # The default value.
+ initial # The initial value.
+ module-name ? # The name of the module to document.
+ : docs * # The documentation for the variable.
+)
{
module-name ?= * ;
@@ -232,6 +239,7 @@
}
}
+
# Generates a general description of the documentation and help system.
#
local rule print-help-top ( )
@@ -268,6 +276,7 @@
print.list-end ;
}
+
# Generate Jam/Boost.Jam command usage information.
#
local rule print-help-usage ( )
@@ -344,13 +353,14 @@
print.list-end ;
}
-# Generates description of options controlling the help system.
-# This automatically reads the options as all variables in the doc
-# module of the form ".option.*".
+
+# Generates description of options controlling the help system. This
+# automatically reads the options as all variables in the doc module of the form
+# ".option.*".
#
local rule print-help-options (
- module-name # The doc module.
- )
+ module-name # The doc module.
+)
{
print.section "Help Options"
These are all the options available for enabling or disabling to control
@@ -376,15 +386,16 @@
}
}
-# Generate brief documentation for all the known items in the section
-# for a module. Possible sections are: "rules", and "variables".
+
+# Generate brief documentation for all the known items in the section for a
+# module. Possible sections are: "rules", and "variables".
#
local rule print-help-module-section (
- module # The module name.
- section # rules or variables.
- : section-head # The title of the section.
- section-description * # The detailed description of the section.
- )
+ module # The module name.
+ section # rules or variables.
+ : section-head # The title of the section.
+ section-description * # The detailed description of the section.
+)
{
if $($(module).$(section))
{
@@ -410,12 +421,13 @@
}
}
+
# Generate documentation for all possible modules. We attempt to list all known
# modules together with a brief description of each.
#
local rule print-help-all (
ignored # Usually the module name, but is ignored here.
- )
+)
{
print.section "Modules"
"These are all the known modules. Use --help <module> to get more"
@@ -442,12 +454,13 @@
}
}
-# Generate documentation for a module. Basic information about
-# the module is generated.
+
+# Generate documentation for a module. Basic information about the module is
+# generated.
#
local rule print-help-module (
- module-name # The module to generate docs for.
- )
+ module-name # The module to generate docs for.
+)
{
# Print the docs.
print.section "Module '$(module-name)'" $($(module-name).docs) ;
@@ -473,12 +486,13 @@
}
}
+
# Generate documentation for a set of rules in a module.
#
local rule print-help-rules (
- module-name # Module of the rules.
- : name * # Optional list of rules to describe.
- )
+ module-name # Module of the rules.
+ : name * # Optional list of rules to describe.
+)
{
name ?= $($(module-name).rules) ;
if [ set.intersection $(name) : $($(module-name).rules) $($(module-name).class-rules) ]
@@ -506,12 +520,13 @@
}
}
+
# Generate documentation for a set of classes in a module.
#
local rule print-help-classes (
- module-name # Module of the classes.
- : name * # Optional list of classes to describe.
- )
+ module-name # Module of the classes.
+ : name * # Optional list of classes to describe.
+)
{
name ?= $($(module-name).classes) ;
if [ set.intersection $(name) : $($(module-name).classes) ]
@@ -550,12 +565,13 @@
}
}
+
# Generate documentation for a set of variables in a module.
#
local rule print-help-variables (
- module-name ? # Module of the variables.
- : name * # Optional list of variables to describe.
- )
+ module-name ? # Module of the variables.
+ : name * # Optional list of variables to describe.
+)
{
name ?= $($(module-name).variables) ;
if [ set.intersection $(name) : $($(module-name).variables) ]
@@ -582,12 +598,13 @@
}
}
+
# Generate documentation for a project.
#
local rule print-help-project (
unused ?
- : jamfile * # The project Jamfile.
- )
+ : jamfile * # The project Jamfile.
+)
{
if $(jamfile<$(jamfile)>.docs[1])
{
@@ -599,13 +616,14 @@
}
}
+
# Generate documentation for a config file.
#
local rule print-help-config (
unused ?
- : type # The type of configuration file user or site.
- config-file # The configuration Jamfile.
- )
+ : type # The type of configuration file user or site.
+ config-file # The configuration Jamfile.
+)
{
if $(jamfile<$(config-file)>.docs[1])
{
@@ -617,17 +635,14 @@
}
}
-local rule __test__
-{
-}
ws = " " ;
# Extract the text from a block of comments.
#
local rule extract-comment (
- var # The name of the variable to extract from.
- )
+ var # The name of the variable to extract from.
+)
{
local comment = ;
local line = $($(var)[1]) ;
@@ -643,11 +658,12 @@
return $(comment) ;
}
+
# Extract s single line of Jam syntax, ignoring any comments.
#
local rule extract-syntax (
- var # The name of the variable to extract from.
- )
+ var # The name of the variable to extract from.
+)
{
local syntax = ;
local line = $($(var)[1]) ;
@@ -664,12 +680,13 @@
return $(syntax) ;
}
-# Extract the next token, this is either a single Jam construct
-# or a comment as a single token.
+
+# Extract the next token, this is either a single Jam construct or a comment as
+# a single token.
#
local rule extract-token (
- var # The name of the variable to extract from.
- )
+ var # The name of the variable to extract from.
+)
{
local parts = ;
while ! $(parts)
@@ -694,18 +711,19 @@
return $(token) ;
}
+
# Scan for a rule declaration as the next item in the variable.
#
local rule scan-rule (
- syntax ? # The first part of the text which contains the rule declaration.
- : var # The name of the variable to extract from.
- )
+ syntax ? # The first part of the text which contains the rule declaration.
+ : var # The name of the variable to extract from.
+)
{
local rule-parts =
[ MATCH "^[$(ws)]*(rule|local[$(ws)]*rule)[$(ws)]+([^$(ws)]+)[$(ws)]*(.*)" : $(syntax:J=" ") ] ;
if $(rule-parts[1])
{
- # mark as doc for rule.
+ # Mark as doc for rule.
local rule-name = $(rule-parts[2]) ;
if $(scope-name)
{
@@ -716,10 +734,10 @@
{
set-rule-doc $(rule-name) $(module-name) $(is-local) : $(comment-block) ;
}
- # parse args of rule.
+ # Parse args of rule.
$(var) = $(rule-parts[3-]) $($(var)) ;
set-rule-arguments-signature $(rule-name) $(module-name) : [ scan-rule-arguments $(var) ] ;
- # scan within this rules scope.
+ # Scan within this rules scope.
local scope-level = [ extract-token $(var) ] ;
local scope-name = $(rule-name) ;
while $(scope-level)
@@ -743,11 +761,12 @@
}
}
+
# Scan the arguments of a rule.
#
local rule scan-rule-arguments (
- var # The name of the variable to extract from.
- )
+ var # The name of the variable to extract from.
+)
{
local arg-syntax = ;
local token = [ extract-token $(var) ] ;
@@ -801,11 +820,13 @@
return $(arg-signature) ;
}
+
# Scan for a variable declaration.
+#
local rule scan-variable (
- syntax ? # The first part of the text which contains the variable declaration.
- : var # The name of the variable to extract from.
- )
+ syntax ? # The first part of the text which contains the variable declaration.
+ : var # The name of the variable to extract from.
+)
{
# [1] = name, [2] = value(s)
local var-parts =
@@ -833,10 +854,12 @@
}
}
+
# Scan a class declaration.
+#
local rule scan-class (
- syntax ? # The syntax text for the class declaration.
- )
+ syntax ? # The syntax text for the class declaration.
+)
{
# [1] = class?, [2] = name, [3] = superclass
local class-parts =
@@ -847,24 +870,25 @@
}
}
+
# Scan a module file for documentation comments. This also invokes any actions
# assigned to the module. The actions are the rules that do the actual output of
# the documentation. This rule is invoked as the header scan rule for the module
# file.
#
rule scan-module (
- target # The module file.
- : text * # The text in the file, one item per line.
- : action * # Rule to call to output docs for the module.
- )
+ target # The module file.
+ : text * # The text in the file, one item per line.
+ : action * # Rule to call to output docs for the module.
+)
{
if $(.option.debug) { ECHO "HELP:" scanning module target '$(target)' ; }
local module-name = $(target:B) ;
local module-documented = ;
local comment-block = ;
local syntax-block = ;
- # This is a hack because we can't get the line of a file if it
- # happens to not have a new-line termination.
+ # This is a hack because we can not get the line of a file if it happens to
+ # not have a new-line termination.
text += "}" ;
while $(text)
{
@@ -902,16 +926,19 @@
}
}
-# Import scan-module to global scope, so that it's available during
-# header scanning phase.
+
+# Import scan-module to global scope, so that it is available during header
+# scanning phase.
+#
IMPORT $(__name__) : scan-module : : doc.scan-module ;
-# Read in a file using the SHELL builtin and return the
-# individual lines as would be done for header scanning.
+
+# Read in a file using the SHELL builtin and return the individual lines as
+# would be done for header scanning.
#
local rule read-file (
- file # The file to read in.
- )
+ file # The file to read in.
+)
{
file = [ path.native [ path.root [ path.make $(file) ] [ path.pwd ] ] ] ;
if ! $(.file<$(file)>.lines)
@@ -940,15 +967,15 @@
return $(.file<$(file)>.lines) ;
}
-# Add a scan action to perform to generate the help documentation.
-# The action rule is passed the name of the module as the first argument.
-# The second argument(s) are optional and passed directly as specified
-# here.
+
+# Add a scan action to perform to generate the help documentation. The action
+# rule is passed the name of the module as the first argument. The second
+# argument(s) are optional and passed directly as specified here.
#
local rule do-scan (
- modules + # The modules to scan and perform the action on.
- : action * # The action rule, plus the secondary arguments to pass to the action rule.
- )
+ modules + # The modules to scan and perform the action on.
+ : action * # The action rule, plus the secondary arguments to pass to the action rule.
+)
{
if $(help-output) = text
{
Modified: branches/release/tools/build/v2/util/indirect.jam
==============================================================================
--- branches/release/tools/build/v2/util/indirect.jam (original)
+++ branches/release/tools/build/v2/util/indirect.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -27,6 +27,7 @@
# expected to be the module in which to invoke the rule by the 'call' rule
# below. Otherwise, the rule will be invoked in the module of this rule's
# caller.
+#
rule make ( rulename bound-args * : context ? )
{
context ?= [ CALLER_MODULE ] ;
@@ -40,6 +41,7 @@
# supplied, the result will be invoked (by 'call', below) in the module of the
# caller. Otherwise, frames > 1 specifies additional call frames to back up in
# order to find the module context.
+#
rule make-qualified ( rulename bound-args * : frames ? )
{
if [ MATCH $(.pattern) : $(rulename) ]
@@ -59,6 +61,7 @@
# Returns the module name in which the given indirect rule will be invoked.
+#
rule get-module ( [indirect-rule] x )
{
local m = [ MATCH $(.pattern) : $(x) ] ;
@@ -71,6 +74,7 @@
# Returns the rulename that will be called when x is invoked.
+#
rule get-rule ( [indirect-rule] x )
{
local m = [ MATCH $(.pattern) : $(x) ] ;
@@ -79,6 +83,7 @@
# Invoke the given indirect-rule.
+#
rule call ( [indirect-rule] r args * : * )
{
return [ modules.call-in [ get-module $(r) ] : [ get-rule $(r) ] $(args)
Modified: branches/release/tools/build/v2/util/numbers.jam
==============================================================================
--- branches/release/tools/build/v2/util/numbers.jam (original)
+++ branches/release/tools/build/v2/util/numbers.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,7 +1,10 @@
-# Copyright 2001, 2002 Dave Abrahams
-# Copyright 2002, 2003 Vladimir Prus
-# 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)
+# Copyright 2001, 2002 Dave Abrahams
+# Copyright 2002, 2003 Vladimir Prus
+# 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)
+
+import errors ;
+
digits = 0 1 2 3 4 5 6 7 8 9 ;
powers = 1 ;
@@ -10,9 +13,8 @@
positive = $(digits[2-]) ;
incr = $(positive[2-]) ;
znatural = $(digits) ;
-zero-test = is zero ; # if $(zero-test[$(n)]) == "is" "zero", n == 0
+zero-test = is zero ; # if $(zero-test[$(n)]) == "is" "zero", n == 0
-import errors : * ;
local rule extend ( )
{
@@ -23,6 +25,19 @@
znatural = $(digits)$(znatural) ;
}
+
+rule trim-leading-zeroes ( value )
+{
+ local value2 = [ MATCH "^0(.*)$" : $(value) ] ;
+ while $(value2)
+ {
+ value = $(value2) ;
+ value2 = [ MATCH "^0(.*)$" : $(value) ] ;
+ }
+ return $(value:E="") ;
+}
+
+
rule check ( numbers * )
{
for local n in $(numbers)
@@ -30,23 +45,24 @@
switch $(n)
{
case *[^0-9]* :
- error $(n) "in" $(numbers) : is not a number ;
+ errors.error $(n) "in" $(numbers) : is not a number ;
}
}
}
+
rule increment ( number )
{
return [ CALC $(number) + 1 ] ;
}
+
rule decrement ( number )
{
- # Previous rule did not allow decrementing zero.
- # Is that what we want?
return [ CALC $(number) - 1 ] ;
}
+
rule range ( start finish ? : step ? )
{
if ! $(finish)
@@ -55,7 +71,7 @@
start = 1 ;
}
step ?= 1 ;
-
+
check $(start) $(finish) $(step) ;
if $(finish) != 0
@@ -64,7 +80,7 @@
{
extend ;
}
-
+
if $(step) = 1
{
return $(positive[$(start)-$(finish)]) ;
@@ -84,26 +100,31 @@
}
}
+
rule less ( n1 n2 )
{
check $(n1) $(n2) ;
- # avoid messy 0 case by appending 1
+ n1 = [ trim-leading-zeroes $(n1) ] ;
+ n2 = [ trim-leading-zeroes $(n2) ] ;
+
+ # Avoid messy 0 case by appending 1.
local l1 = [ range 2 [ log10 $(n1)1 ] ] ;
local l2 = [ range 2 [ log10 $(n2)1 ] ] ;
-
- # number of digits mismatch?
+
+ # Number of digits mismatch?
if ( $(l1) < $(l2) ) || ( ( $(l1) = $(l2) ) && $(n1) < $(n2) )
{
return true ;
}
}
+
rule log10 ( number )
{
switch $(number)
{
- case *[^0-9]* : error $(number) is not a number ;
- case 0 : error can't take log of zero ;
+ case *[^0-9]* : errors.error $(number) is not a number ;
+ case 0 : errors.error can't take log of zero ;
case [1-9] : return 0 ;
case [1-9]? : return 1 ;
case [1-9]?? : return 2 ;
@@ -123,23 +144,23 @@
{
chars = $(chars[2-]) ;
}
-
if ! $(chars)
{
- error can't take log of zero ;
+ errors.error can't take log of zero ;
}
else
{
- return [ sequence.length $(chars) ] ;
+ return [ decrement [ sequence.length $(chars) ] ] ;
}
}
}
}
+
rule __test__ ( )
{
import assert ;
-
+
assert.result 1 : increment 0 ;
assert.result 2 : increment 1 ;
assert.result 1 : decrement 2 ;
@@ -149,10 +170,9 @@
assert.result 99 : increment 98 ;
assert.result 99 : decrement 100 ;
assert.result 100 : increment 99 ;
- # This just makes debugging output too large
- # assert.result 1000 : increment 999 ;
- # assert.result 999 : decrement 1000 ;
-
+ assert.result 999 : decrement 1000 ;
+ assert.result 1000 : increment 999 ;
+
assert.result 1 2 3 : range 3 ;
assert.result 1 2 3 4 5 6 7 8 9 10 11 12 : range 12 ;
assert.result 3 4 5 6 7 8 9 10 11 : range 3 11 ;
@@ -160,40 +180,53 @@
assert.result 1 4 7 10 : range 10 : 3 ;
assert.result 2 4 6 8 10 : range 2 10 : 2 ;
assert.result 25 50 75 100 : range 25 100 : 25 ;
-
- assert.true less 1 2 ;
- assert.true less 1 12 ;
- assert.true less 1 21 ;
+
+ assert.result 0 : trim-leading-zeroes 0 ;
+ assert.result 1234 : trim-leading-zeroes 1234 ;
+ assert.result 123456 : trim-leading-zeroes 0000123456 ;
+ assert.result 10000123456 : trim-leading-zeroes 10000123456 ;
+ assert.result 10000 : trim-leading-zeroes 10000 ;
+ assert.result 10000 : trim-leading-zeroes 00010000 ;
+
+ assert.true less 1 2 ;
+ assert.true less 1 12 ;
+ assert.true less 1 21 ;
+ assert.true less 005 217 ;
assert.false less 0 0 ;
-
- # TEMPORARY disabled, because nested "try"/"catch" do not work, I don't the
- # time to fix that right now.
- if $(0)
- {
+ assert.false less 03 3 ;
+ assert.false less 3 03 ;
+ assert.true less 005 217 ;
+ assert.true less 0005 217 ;
+ assert.true less 5 00217 ;
+
+ # TEMPORARY disabled, because nested "try"/"catch" do not work and I do no
+ # have the time to fix that right now.
+ if $(0)
+ {
try ;
{
decrement 0 ;
}
catch can't decrement zero! ;
-
+
try ;
{
check foo ;
}
catch : not a number ;
-
+
try ;
{
increment foo ;
}
catch : not a number ;
-
+
try ;
{
log10 0 ;
}
catch can't take log of zero ;
-
+
try ;
{
log10 000 ;
@@ -201,14 +234,18 @@
catch can't take log of zero ;
}
-
+
assert.result 0 : log10 1 ;
assert.result 0 : log10 9 ;
assert.result 1 : log10 10 ;
assert.result 1 : log10 99 ;
+ assert.result 2 : log10 100 ;
+ assert.result 2 : log10 101 ;
assert.result 2 : log10 125 ;
- assert.result 11 : log10 12345678901 ;
-
+ assert.result 2 : log10 999 ;
+ assert.result 3 : log10 1000 ;
+ assert.result 10 : log10 12345678901 ;
+
for local x in [ range 75 110 : 5 ]
{
for local y in [ range $(x) 111 : 3 ]
@@ -219,7 +256,7 @@
}
}
}
-
+
for local x in [ range 90 110 : 2 ]
{
for local y in [ range 80 $(x) : 4 ]
Modified: branches/release/tools/build/v2/util/os.jam
==============================================================================
--- branches/release/tools/build/v2/util/os.jam (original)
+++ branches/release/tools/build/v2/util/os.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -15,7 +15,6 @@
return [ modules.peek .ENVIRON : $(variable-names) ] ;
}
-
.name = [ modules.peek : OS ] ;
.platform = [ modules.peek : OSPLAT ] ;
.version = [ modules.peek : OSVER ] ;
@@ -24,7 +23,7 @@
local rule constant ( c : os ? )
{
os ?= $(.name) ;
- # First look for platform-specific name, then general value
+ # First look for a platform-specific name, then the general value.
local variables = .$(c)-$(os) .$(c) ;
local result = $($(variables)) ;
return $(result[1]) ;
Modified: branches/release/tools/build/v2/util/path.jam
==============================================================================
--- branches/release/tools/build/v2/util/path.jam (original)
+++ branches/release/tools/build/v2/util/path.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -6,22 +6,23 @@
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
-# Performs various path manipulations. Paths are always in a 'normalized'
-# representation. In it, a path may be either:
+# Performs various path manipulations. Paths are always in a 'normalized'
+# representation. In it, a path may be either:
#
# - '.', or
#
-# - ['/'] [ ( '..' '/' )* (token '/')* token ]
+# - ['/'] [ ( '..' '/' )* (token '/')* token ]
#
-# In plain english, path can be rooted, '..' elements are allowed only
-# at the beginning, and it never ends in slash, except for path consisting
-# of slash only.
+# In plain english, path can be rooted, '..' elements are allowed only at the
+# beginning, and it never ends in slash, except for path consisting of slash
+# only.
import errors ;
import modules ;
import regex ;
import sequence ;
import set ;
+import version ;
os = [ modules.peek : OS ] ;
@@ -35,7 +36,8 @@
}
}
-# Converts the native path into normalized form.
+
+# Converts the native path into normalized form.
#
rule make ( native )
{
@@ -43,7 +45,7 @@
}
-# Builds native representation of the path.
+# Builds native representation of the path.
#
rule native ( path )
{
@@ -51,7 +53,7 @@
}
-# Tests if a path is rooted.
+# Tests if a path is rooted.
#
rule is-rooted ( path )
{
@@ -59,7 +61,7 @@
}
-# Tests if a path has a parent.
+# Tests if a path has a parent.
#
rule has-parent ( path )
{
@@ -74,7 +76,7 @@
}
-# Returns the path without any directory components.
+# Returns the path without any directory components.
#
rule basename ( path )
{
@@ -82,7 +84,7 @@
}
-# Returns parent directory of the path. If no parent exists, error is issued.
+# Returns parent directory of the path. If no parent exists, error is issued.
#
rule parent ( path )
{
@@ -94,8 +96,8 @@
}
else
{
- # Strip everything at the end of path up to and including
- # the last slash
+ # Strip everything at the end of path up to and including the last
+ # slash.
local result = [ regex.match "((.*)/)?([^/]+)" : $(path) : 2 3 ] ;
# Did we strip what we shouldn't?
@@ -127,8 +129,8 @@
}
-# Returns path2 such that "[ join path path2 ] = .".
-# The path may not contain ".." element or be rooted.
+# Returns path2 such that "[ join path path2 ] = .". The path may not contain
+# ".." element or be rooted.
#
rule reverse ( path )
{
@@ -149,31 +151,12 @@
}
-# Auxillary rule: does all the semantic of 'join', except for error cheching.
-# The error checking is separated because this rule is recursive, and I don't
-# like the idea of checking the same input over and over.
-#
-local rule join-imp ( elements + )
-{
- local result = ;
- if ! $(elements[1])
- {
- result = [ NORMALIZE_PATH "/" "$(elements[2-])" ] ;
- }
- else
- {
- result = [ NORMALIZE_PATH "$(elements)" ] ;
- }
- return $(result) ;
-}
-
-
-# Contanenates the passed path elements. Generates an error if
-# any element other than the first one is rooted.
+# Concatenates the passed path elements. Generates an error if any element other
+# than the first one is rooted. Skips any empty or undefined path elements.
#
rule join ( elements + )
{
- if ! $(elements[2])
+ if ! $(elements[2-])
{
return $(elements[1]) ;
}
@@ -183,27 +166,50 @@
{
if [ is-rooted $(e) ]
{
- errors.error only first element may be rooted ;
+ errors.error only the first element may be rooted ;
+ }
+ }
+ if [ version.check-jam-version 3 1 17 ]
+ {
+ return [ NORMALIZE_PATH "$(elements)" ] ;
+ }
+ else
+ {
+ # Boost Jam prior to version 3.1.17 had problems with its
+ # NORMALIZE_PATH rule in case you passed it a leading backslash
+ # instead of a slash, in some cases when you sent it an empty
+ # initial path element and possibly some others. At least some of
+ # those cases were being hit and relied upon when calling this rule
+ # from the path.make-NT rule.
+ if ! $(elements[1]) && $(elements[2])
+ {
+ return [ NORMALIZE_PATH "/" "$(elements[2-])" ] ;
+ }
+ else
+ {
+ return [ NORMALIZE_PATH "$(elements)" ] ;
}
}
- return [ join-imp $(elements) ] ;
}
}
-# If 'path' is relative, it is rooted at 'root'. Otherwise, it's unchanged.
+# If 'path' is relative, it is rooted at 'root'. Otherwise, it is unchanged.
#
rule root ( path root )
{
- if [ is-rooted $(path) ] {
+ if [ is-rooted $(path) ]
+ {
return $(path) ;
- } else {
+ }
+ else
+ {
return [ join $(root) $(path) ] ;
}
}
-# Returns the current working directory.
+# Returns the current working directory.
#
rule pwd ( )
{
@@ -219,19 +225,20 @@
}
-# Returns the list of files matching the given pattern in the
-# specified directory. Both directories and patterns are
-# supplied as portable paths. Each pattern should be non-absolute
-# path, and can't contain "." or ".." elements. Each slash separated
-# element of pattern can contain the following special characters:
-# - '?', which match any character
-# - '*', which matches arbitrary number of characters.
-# A file $(d)/e1/e2/e3 (where 'd' is in $(dirs)) matches pattern p1/p2/p3
-# if and only if e1 matches p1, e2 matches p2 and so on.
-#
-# For example:
-# [ glob . : *.cpp ]
-# [ glob . : */build/Jamfile ]
+# Returns the list of files matching the given pattern in the specified
+# directory. Both directories and patterns are supplied as portable paths. Each
+# pattern should be non-absolute path, and can't contain "." or ".." elements.
+# Each slash separated element of pattern can contain the following special
+# characters:
+# - '?', which match any character
+# - '*', which matches arbitrary number of characters.
+# A file $(d)/e1/e2/e3 (where 'd' is in $(dirs)) matches pattern p1/p2/p3 if and
+# only if e1 matches p1, e2 matches p2 and so on.
+#
+# For example:
+# [ glob . : *.cpp ]
+# [ glob . : */build/Jamfile ]
+#
rule glob ( dirs * : patterns + : exclude-patterns * )
{
local result ;
@@ -262,12 +269,11 @@
}
-# Recursive version of GLOB. Builds the glob of files while
-# also searching in the subdirectories of the given roots. An
-# optional set of exclusion patterns will filter out the
-# matching entries from the result. The exclusions also apply
-# to the subdirectory scanning, such that directories that
-# match the exclusion patterns will not be searched.
+# Recursive version of GLOB. Builds the glob of files while also searching in
+# the subdirectories of the given roots. An optional set of exclusion patterns
+# will filter out the matching entries from the result. The exclusions also
+# apply to the subdirectory scanning, such that directories that match the
+# exclusion patterns will not be searched.
#
rule glob-tree ( roots * : patterns + : exclude-patterns * )
{
@@ -302,7 +308,7 @@
}
-# Returns true is the specified file exists.
+# Returns true is the specified file exists.
#
rule exists ( file )
{
@@ -311,9 +317,9 @@
NATIVE_RULE path : exists ;
-# Find out the absolute name of path and returns the list of all the parents,
-# starting with the immediate one. Parents are returned as relative names.
-# If 'upper_limit' is specified, directories above it will be pruned.
+# Find out the absolute name of path and returns the list of all the parents,
+# starting with the immediate one. Parents are returned as relative names. If
+# 'upper_limit' is specified, directories above it will be pruned.
#
rule all-parents ( path : upper_limit ? : cwd ? )
{
@@ -349,8 +355,8 @@
}
-# Search for 'pattern' in parent directories of 'dir', up till and including
-# 'upper_limit', if it is specified, or till the filesystem root otherwise.
+# Search for 'pattern' in parent directories of 'dir', up till and including
+# 'upper_limit', if it is specified, or till the filesystem root otherwise.
#
rule glob-in-parents ( dir : patterns + : upper-limit ? )
{
@@ -366,8 +372,8 @@
}
-# Assuming 'child' is a subdirectory of 'parent', return the relative
-# path from 'parent' to 'child'
+# Assuming 'child' is a subdirectory of 'parent', return the relative path from
+# 'parent' to 'child'.
#
rule relative ( child parent )
{
@@ -429,8 +435,9 @@
}
-# Returns the list of paths which are used by the operating system
-# for looking up programs
+# Returns the list of paths which are used by the operating system for looking
+# up programs.
+#
rule programs-path ( )
{
local result ;
@@ -446,27 +453,38 @@
}
+# Converts native Windows paths into our internal canonic path representation.
+# Supports 'invalid' paths containing multiple successive path separator
+# characters.
+#
+# TODO: Check and if needed add support for Windows 'X:file' path format where
+# the file is located in the current folder on drive X.
+#
rule make-NT ( native )
{
- local tokens = [ regex.split $(native) "[/\\]" ] ;
local result ;
- # Handle paths ending with slashes
- if $(tokens[-1]) = ""
+ if [ version.check-jam-version 3 1 17 ]
{
- tokens = $(tokens[1--2]) ; # discard the empty element
+ result = [ NORMALIZE_PATH $(native) ] ;
}
-
- result = [ path.join $(tokens) ] ;
-
- if [ regex.match "(^.:)" : $(native) ]
+ else
{
- result = /$(result) ;
+ # This old implementation is really fragile due to a not so clear way
+ # NORMALIZE_PATH rule worked in Boost.Jam versions prior to 3.1.17. E.g.
+ # path.join would mostly ignore empty path elements but would root the
+ # joined path in case the initial two path elements were empty or some
+ # similar accidental wierdness.
+ result = [ path.join [ regex.split $(native) "[/\\]" ] ] ;
}
- if $(native) = ""
+ # We need to add an extra '/' in front in case this is a rooted Windows path
+ # starting with a drive letter and not a path separator character since the
+ # builtin NORMALIZE_PATH rule has no knowledge of this leading drive letter
+ # and treats it as a regular folder name.
+ if [ regex.match "(^.:)" : $(native) ]
{
- result = "." ;
+ result = /$(result) ;
}
return $(result) ;
@@ -492,7 +510,7 @@
rule make-UNIX ( native )
{
# VP: I have no idea now 'native' can be empty here! But it can!
- if $(native) = ""
+ if ! $(native)
{
errors.error "Empty path passed to 'make-UNIX'" ;
}
@@ -518,16 +536,17 @@
rule native-CYGWIN ( path )
{
local result = $(path) ;
- if [ regex.match "(^/.:)" : $(path) ] # win absolute
+ if [ regex.match "(^/.:)" : $(path) ] # Windows absolute path.
{
- result = [ MATCH "^/?(.*)" : $(path) ] ; # remove leading '/'
+ result = [ MATCH "^/?(.*)" : $(path) ] ; # Remove leading '/'.
}
return [ native-UNIX $(result) ] ;
}
-# split-VMS: splits input native path into
-# device dir file (each part is optional),
+# split-path-VMS: splits input native path into device dir file (each part is
+# optional).
+#
# example:
#
# dev:[dir]file.c => dev: [dir] file.c
@@ -545,12 +564,11 @@
# Converts a native VMS path into a portable path spec.
#
-# Does not handle current-device absolute paths such
-# as "[dir]File.c" as it is not clear how to represent
-# them in the portable path notation.
+# Does not handle current-device absolute paths such as "[dir]File.c" as it is
+# not clear how to represent them in the portable path notation.
#
-# Adds a trailing dot (".") to the file part if no extension
-# is present (helps when converting it back into native path).
+# Adds a trailing dot (".") to the file part if no extension is present (helps
+# when converting it back into native path).
#
rule make-VMS ( native )
{
@@ -606,7 +624,7 @@
if ! [ MATCH (\\.) : $(file) ]
{
#
- # Always add "." to end of non-extension file
+ # Always add "." to end of non-extension file.
#
file = $(file). ;
}
@@ -621,8 +639,8 @@
# Converts a portable path spec into a native VMS path.
#
-# Relies on having at least one dot (".") included in the file
-# name to be able to differentiate it ftom the directory part.
+# Relies on having at least one dot (".") included in the file name to be able
+# to differentiate it from the directory part.
#
rule native-VMS ( path )
{
@@ -767,12 +785,47 @@
assert.result "foo/bar/giz" : make "foo/bar/giz" ;
assert.result "foo/bar/giz" : make "foo\\bar\\giz" ;
+ assert.result "foo" : make "foo/" ;
+ assert.result "foo" : make "foo\\" ;
assert.result "foo" : make "foo/." ;
assert.result "foo" : make "foo/bar/.." ;
+ assert.result "foo" : make "foo/bar/../" ;
+ assert.result "foo" : make "foo/bar/..\\" ;
assert.result "foo/bar" : make "foo/././././bar" ;
assert.result "/foo" : make "\\foo" ;
assert.result "/D:/My Documents" : make "D:\\My Documents" ;
assert.result "/c:/boost/tools/build/new/project.jam" : make "c:\\boost\\tools\\build\\test\\..\\new\\project.jam" ;
+
+ # Test processing 'invalid' paths containing multiple successive path
+ # separators.
+ assert.result "foo" : make "foo//" ;
+ assert.result "foo" : make "foo///" ;
+ assert.result "foo" : make "foo\\\\" ;
+ assert.result "foo" : make "foo\\\\\\" ;
+ assert.result "/foo" : make "//foo" ;
+ assert.result "/foo" : make "///foo" ;
+ assert.result "/foo" : make "\\\\foo" ;
+ assert.result "/foo" : make "\\\\\\foo" ;
+ assert.result "/foo" : make "\\/\\/foo" ;
+ assert.result "foo/bar" : make "foo//\\//\\\\bar//\\//\\\\\\//\\//\\\\" ;
+ assert.result "foo" : make "foo/bar//.." ;
+ assert.result "foo/bar" : make "foo/bar/giz//.." ;
+ assert.result "foo/giz" : make "foo//\\//\\\\bar///\\\\//\\\\////\\/..///giz\\//\\\\\\//\\//\\\\" ;
+ assert.result "../../../foo" : make "..///.//..///.//..////foo///" ;
+
+ # Test processing 'invalid' rooted paths with too many '..' path elements
+ # that would place them before the root.
+ assert.result : make "/.." ;
+ assert.result : make "/../" ;
+ assert.result : make "/../." ;
+ assert.result : make "/.././" ;
+ assert.result : make "/foo/../bar/giz/.././././../../." ;
+ assert.result : make "/foo/../bar/giz/.././././../.././" ;
+ assert.result : make "//foo/../bar/giz/.././././../../." ;
+ assert.result : make "//foo/../bar/giz/.././././../.././" ;
+ assert.result : make "\\\\foo/../bar/giz/.././././../../." ;
+ assert.result : make "\\\\foo/../bar/giz/.././././../.././" ;
+ assert.result : make "/..///.//..///.//..////foo///" ;
assert.result "foo\\bar\\giz" : native "foo/bar/giz" ;
assert.result "foo" : native "foo" ;
Modified: branches/release/tools/build/v2/util/print.jam
==============================================================================
--- branches/release/tools/build/v2/util/print.jam (original)
+++ branches/release/tools/build/v2/util/print.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -16,22 +16,22 @@
# The current output target. Defaults to console.
output-target = console ;
-# The current output type. Defaults to plain.
+# The current output type. Defaults to plain. Other possible values are "html".
output-type = plain ;
# Whitespace.
.whitespace = [ string.whitespace ] ;
-# Set the target and type of output to generate. This sets both
-# the destination output and the type of docs to generate to that
-# output. The target can be either a file or "console" for echoing
-# to the console. If the type of output is not specified it defaults
-# to plain text.
+
+# Set the target and type of output to generate. This sets both the destination
+# output and the type of docs to generate to that output. The target can be
+# either a file or "console" for echoing to the console. If the type of output
+# is not specified it defaults to plain text.
#
rule output (
- target # The target file or device; file or "console".
- type ? # The type of output; "plain", or "html".
- )
+ target # The target file or device; file or "console".
+ type ? # The type of output; "plain" or "html".
+)
{
type ?= plain ;
if $(output-target) != $(target)
@@ -57,15 +57,14 @@
}
}
-# Generate a section with a description. The type of output can be
-# controlled by the value of the 'output-type' variable. If not set
-# it defaults to 'console' indicating immediate display to the console.
-# Other possible values are: 'html-file'.
+
+# Generate a section with a description. The type of output can be controlled by
+# the value of the 'output-type' variable.
#
rule section (
- name # The name of the section.
- description * # A number of description lines.
- )
+ name # The name of the section.
+ description * # A number of description lines.
+)
{
if $(output-type) = plain
{
@@ -165,10 +164,9 @@
}
}
-# Generate the start of a list of items. The type of output can be
-# controlled by the value of the 'output-type' variable. If not set
-# it defaults to 'console' indicating immediate display to the console.
-# Other possible values are: 'html-file'.
+
+# Generate the start of a list of items. The type of output can be controlled by
+# the value of the 'output-type' variable.
#
rule list-start ( )
{
@@ -181,14 +179,13 @@
}
}
-# Generate an item in a list. The type of output can be
-# controlled by the value of the 'output-type' variable. If not set
-# it defaults to 'console' indicating immediate display to the console.
-# Other possible values are: 'html-file'.
+
+# Generate an item in a list. The type of output can be controlled by the value
+# of the 'output-type' variable.
#
rule list-item (
- item + # The item to list.
- )
+ item + # The item to list.
+)
{
if $(output-type) = plain
{
@@ -200,10 +197,9 @@
}
}
-# Generate the end of a list of items. The type of output can be
-# controlled by the value of the 'output-type' variable. If not set
-# it defaults to 'console' indicating immediate display to the console.
-# Other possible values are: 'html-file'.
+
+# Generate the end of a list of items. The type of output can be controlled by
+# the value of the 'output-type' variable.
#
rule list-end ( )
{
@@ -217,13 +213,14 @@
}
}
-# Split the given text into separate lines, word-wrapping to a margin.
-# The default margin is 78 characters.
+
+# Split the given text into separate lines, word-wrapping to a margin. The
+# default margin is 78 characters.
#
rule split-at-words (
- text + # The text to split.
- : margin ? # An optional margin, default is 78.
- )
+ text + # The text to split.
+ : margin ? # An optional margin, default is 78.
+)
{
local lines = ;
text = [ string.words $(text:J=" ") ] ;
@@ -264,15 +261,16 @@
return $(lines) ;
}
-# Generate a set of fixed lines. Each single item passed in is
-# output on a separate line. For console this just echos each line,
-# but for html this will split them with <br>.
+
+# Generate a set of fixed lines. Each single item passed in is output on a
+# separate line. For console this just echos each line, but for html this will
+# split them with <br>.
#
rule lines (
- text * # The lines of text.
- : indent ? # Optional indentation prepended to each line after the first one.
- outdent ? # Optional indentation to prepend to the first line.
- )
+ text * # The lines of text.
+ : indent ? # Optional indentation prepended to each line after the first one.
+ outdent ? # Optional indentation to prepend to the first line.
+)
{
text ?= "" ;
indent ?= "" ;
@@ -296,19 +294,20 @@
}
}
-# Output text directly to the current target. When doing output
-# to a file, one can indicate if the text should be output to
-# "prefix" it, as the "body" (default), or "suffix" of the file. This is
-# independant of the actual execution order of the text rule. This rule
-# invokes a singular action, one action only once, which does the
-# build of the file. Therefore actions on the target outside of this
-# rule will happen entirely before and/or after all output using this rule.
+
+# Output text directly to the current target. When doing output to a file, one
+# can indicate if the text should be output to "prefix" it, as the "body"
+# (default), or "suffix" of the file. This is independant of the actual
+# execution order of the text rule. This rule invokes a singular action, one
+# action only once, which does the build of the file. Therefore actions on the
+# target outside of this rule will happen entirely before and/or after all
+# output using this rule.
#
rule text (
- strings * # The strings of text to output.
- : overwrite ? # true to overwrite the output (if it is a file)
- : prefix-body-suffix ? # Indication to output prefix, body, or suffix (for a file).
- )
+ strings * # The strings of text to output.
+ : overwrite ? # true to overwrite the output (if it is a file)
+ : prefix-body-suffix ? # Indication to output prefix, body, or suffix (for a file).
+)
{
prefix-body-suffix ?= body ;
if $(output-target) = console
@@ -350,21 +349,24 @@
$($(output-target).text-suffix) ;
}
+
# Outputs the text to the current targets, after word-wrapping it.
+#
rule wrapped-text ( text + )
{
local lines = [ split-at-words $(text) ] ;
text $(lines) ;
}
-# Escapes text into html/xml printable equivalents.
-# Does not know about tags and therefore tags fed into
-# this will also be escaped. Currently escapes space, "<", ">", and "&".
+
+# Escapes text into html/xml printable equivalents. Does not know about tags and
+# therefore tags fed into this will also be escaped. Currently escapes space,
+# "<", ">", and "&".
#
rule escape-html (
- text + # The text to escape.
- : space ? # What to replace spaces with, defaults to " ".
- )
+ text + # The text to escape.
+ : space ? # What to replace spaces with, defaults to " ".
+)
{
local html-text = ;
while $(text)
@@ -383,24 +385,26 @@
return $(html-text) ;
}
-# Outputs the text strings collected by the text rule to the output
-# file.
+
+# Outputs the text strings collected by the text rule to the output file.
#
actions quietly text-action
{
@($(STDOUT):E=$(text-content:J=$(nl))) $(text-redirect) "$(<)"
}
-local rule __test__ ( )
+
+rule __test__ ( )
{
import assert ;
- assert.result one two three : split-at-words one two three : 5 ;
+ assert.result one two three : split-at-words one two three : 5 ;
assert.result "one two" three : split-at-words one two three : 8 ;
assert.result "one two" three : split-at-words one two three : 9 ;
assert.result "one two three" : split-at-words one two three ;
- # VP, 2004-12-03 The following test fails for some reason,
- # so commenting it out.
+
+ # VP, 2004-12-03 The following test fails for some reason, so commenting it
+ # out.
#assert.result "one two three" "&<>" :
# escape-html "one two three" "&<>" ;
}
Modified: branches/release/tools/build/v2/util/sequence.jam
==============================================================================
--- branches/release/tools/build/v2/util/sequence.jam (original)
+++ branches/release/tools/build/v2/util/sequence.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -8,15 +8,17 @@
import numbers ;
import modules ;
-# Note that algorithms in this module execute largely in the caller's
-# module namespace, so that local rules can be used as function
-# objects. Also note that most predicates can be multi-element
-# lists. In that case, all but the first element are prepended to the
-# first argument which is passed to the rule named by the first
-# element.
-# Return the elements e of $(sequence) for which [ $(predicate) e ]
-# has a non-null value.
+# Note that algorithms in this module execute largely in the caller's module
+# namespace, so that local rules can be used as function objects. Also note that
+# most predicates can be multi-element lists. In that case, all but the first
+# element are prepended to the first argument which is passed to the rule named
+# by the first element.
+
+
+# Return the elements e of $(sequence) for which [ $(predicate) e ] has a
+# non-null value.
+#
rule filter ( predicate + : sequence * )
{
local caller = [ CALLER_MODULE ] ;
@@ -32,8 +34,10 @@
return $(result) ;
}
-# return a new sequence consisting of [ $(function) $(e) ] for each
-# element e of $(sequence).
+
+# Return a new sequence consisting of [ $(function) $(e) ] for each element e of
+# $(sequence).
+#
rule transform ( function + : sequence * )
{
local caller = [ CALLER_MODULE ] ;
@@ -46,6 +50,7 @@
return $(result) ;
}
+
rule reverse ( s * )
{
local r ;
@@ -65,7 +70,9 @@
}
}
-# insertion-sort s using the BinaryPredicate ordered.
+
+# Insertion-sort s using the BinaryPredicate ordered.
+#
rule insertion-sort ( s * : ordered * )
{
if ! $(ordered)
@@ -111,14 +118,17 @@
}
}
-# merge two ordered sequences using the BinaryPredicate ordered.
+
+# Merge two ordered sequences using the BinaryPredicate ordered.
+#
rule merge ( s1 * : s2 * : ordered * )
{
ordered ?= sequence.less ;
local result__ ;
local caller = [ CALLER_MODULE ] ;
- while $(s1) && $(s2) {
+ while $(s1) && $(s2)
+ {
if [ modules.call-in $(caller) : $(ordered) $(s1[1]) $(s2[1]) ]
{
result__ += $(s1[1]) ;
@@ -141,15 +151,19 @@
return $(result__) ;
}
-# join the elements of s into one long string. If joint is supplied,
-# it is used as a separator.
+
+# Join the elements of s into one long string. If joint is supplied, it is used
+# as a separator.
+#
rule join ( s * : joint ? )
{
joint ?= "" ;
return $(s:J=$(joint)) ;
}
+
# Find the length of any sequence.
+#
rule length ( s * )
{
local result = 0 ;
@@ -160,6 +174,7 @@
return $(result) ;
}
+
rule unique ( list * : stable ? )
{
local result ;
@@ -188,8 +203,10 @@
return $(result) ;
}
-# Returns the maximum number in 'elements'. Uses 'ordered' for comparisons,
-# or 'numbers.less' is none is provided.
+
+# Returns the maximum number in 'elements'. Uses 'ordered' for comparisons, or
+# 'numbers.less' is none is provided.
+#
rule max-element ( elements + : ordered ? )
{
ordered ?= numbers.less ;
@@ -205,8 +222,10 @@
return $(max) ;
}
-# Returns all of 'elements' for which corresponding element in parallel
-# list 'rank' is equal to the maximum value in 'rank'.
+
+# Returns all of 'elements' for which corresponding element in parallel list
+# 'rank' is equal to the maximum value in 'rank'.
+#
rule select-highest-ranked ( elements * : ranks * )
{
if $(elements)
@@ -228,9 +247,9 @@
NATIVE_RULE sequence : select-highest-ranked ;
-local rule __test__ ( )
+rule __test__ ( )
{
- # use a unique module so we can test the use of local rules.
+ # Use a unique module so we can test the use of local rules.
module sequence.__test__
{
import assert ;
@@ -244,10 +263,9 @@
}
}
- assert.result 4 6 4 2 8
- : sequence.filter is-even : 1 4 6 3 4 7 2 3 8 ;
+ assert.result 4 6 4 2 8 : sequence.filter is-even : 1 4 6 3 4 7 2 3 8 ;
- # test that argument binding works
+ # Test that argument binding works.
local rule is-equal-test ( x y )
{
if $(x) = $(y)
@@ -302,18 +320,15 @@
local p2 = x ;
for local i in 1 2 3 4 5 6 7 8
{
- p2 = $(p2) $(p2) ;
+ p2 = $(p2) $(p2) ;
}
assert.result 256 : sequence.length $(p2) ;
- assert.result 1 2 3 4 5
- : sequence.unique 1 2 3 2 4 3 3 5 5 5 ;
+ assert.result 1 2 3 4 5 : sequence.unique 1 2 3 2 4 3 3 5 5 5 ;
- assert.result 5
- : sequence.max-element 1 3 5 0 4 ;
+ assert.result 5 : sequence.max-element 1 3 5 0 4 ;
- assert.result e-3 h-3
- : sequence.select-highest-ranked e-1 e-3 h-3 m-2 : 1 3 3 2 ;
+ assert.result e-3 h-3 : sequence.select-highest-ranked e-1 e-3 h-3 m-2 : 1 3 3 2 ;
assert.result 7 6 5 4 3 2 1 : sequence.reverse 1 2 3 4 5 6 7 ;
}
Modified: branches/release/tools/build/v2/util/set.jam
==============================================================================
--- branches/release/tools/build/v2/util/set.jam (original)
+++ branches/release/tools/build/v2/util/set.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,17 +1,17 @@
-# Copyright 2001, 2002 Dave Abrahams
-# Copyright 2003 Vladimir Prus
-# 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)
-
-# difference
-# returns the elements of B that are not in A
-rule difference ( B * : A * )
+# Copyright 2001, 2002 Dave Abrahams
+# Copyright 2003 Vladimir Prus
+# 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)
+
+
+# Returns the elements of set1 that are not in set2.
+#
+rule difference ( set1 * : set2 * )
{
local result = ;
- local element ;
- for element in $(B)
+ for local element in $(set1)
{
- if ! ( $(element) in $(A) )
+ if ! ( $(element) in $(set2) )
{
result += $(element) ;
}
@@ -21,9 +21,9 @@
NATIVE_RULE set : difference ;
-# intersection set1 : set2
+
+# Removes all the items appearing in both set1 & set2.
#
-# Removes from set1 any items which don't appear in set2 and returns the result.
rule intersection ( set1 * : set2 * )
{
local result ;
@@ -37,6 +37,10 @@
return $(result) ;
}
+
+# Returns whether set1 & set2 contain the same elements. Note that this ignores
+# any element ordering differences as well as any element duplication.
+#
rule equal ( set1 * : set2 * )
{
if $(set1) in $(set2) && ( $(set2) in $(set1) )
@@ -45,18 +49,15 @@
}
}
+
rule __test__ ( )
{
import assert ;
-
- assert.result 0 1 4 6 8 9
- : difference 0 1 2 3 4 5 6 7 8 9 : 2 3 5 7 ;
-
- assert.result 2 5 7 : intersection 0 1 2 4 5 6 7 8 9 : 2 3 5 7 ;
-
- assert.true equal 1 1 2 3 : 3 2 2 1 ;
-
- assert.false equal 2 3 : 3 2 2 1 ;
-}
+ assert.result 0 1 4 6 8 9 : difference 0 1 2 3 4 5 6 7 8 9 : 2 3 5 7 ;
+ assert.result 2 5 7 : intersection 0 1 2 4 5 6 7 8 9 : 2 3 5 7 ;
+ assert.true equal : ;
+ assert.true equal 1 1 2 3 : 3 2 2 1 ;
+ assert.false equal 2 3 : 3 2 2 1 ;
+}
Modified: branches/release/tools/build/v2/util/string.jam
==============================================================================
--- branches/release/tools/build/v2/util/string.jam (original)
+++ branches/release/tools/build/v2/util/string.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -1,10 +1,11 @@
-# Copyright 2002 Dave Abrahams
-# Copyright 2002, 2003 Rene Rivera
-# 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)
+# Copyright 2002 Dave Abrahams
+# Copyright 2002, 2003 Rene Rivera
+# 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)
import regex ;
+
# Characters considered whitespace, as a list.
.whitespace-chars = " " " " "
" ;
@@ -12,6 +13,7 @@
# Characters considered whitespace, as a single string.
.whitespace = $(.whitespace-chars:J="") ;
+
# Returns the canonical set of whitespace characters, as a list.
#
rule whitespace-chars ( )
@@ -19,6 +21,7 @@
return $(.whitespace-chars) ;
}
+
# Returns the canonical set of whitespace characters, as a single string.
#
rule whitespace ( )
@@ -26,11 +29,12 @@
return $(.whitespace) ;
}
-# Splits the given string into a list of strings composed
-# of each character of the string in sequence.
+
+# Splits the given string into a list of strings composed of each character of
+# the string in sequence.
#
rule chars (
- string # The string to split.
+ string # The string to split.
)
{
local result ;
@@ -40,18 +44,19 @@
string = $(s[9]) ;
result += $(s[1-8]) ;
}
-
- # trim off empty strings
+
+ # Trim off empty strings.
while $(result[1]) && ! $(result[-1])
{
result = $(result[1--2]) ;
}
-
+
return $(result) ;
}
-# Apply a set of standard transformations to string to produce an
-# abbreviation no more than 5 characters long
+
+# Apply a set of standard transformations to string to produce an abbreviation
+# no more than 5 characters long.
#
rule abbreviate ( string )
{
@@ -60,22 +65,22 @@
{
return $(r) ;
}
- # Anything less than 4 characters gets no abbreviation
+ # Anything less than 4 characters gets no abbreviation.
else if ! [ MATCH (....) : $(string) ]
{
- $(.abbreviated-$(string)) = $(string) ;
+ .abbreviated-$(string) = $(string) ;
return $(string) ;
}
else
{
- # Separate the initial letter in case it's a vowel
+ # Separate the initial letter in case it's a vowel.
local s1 = [ MATCH ^(.)(.*) : $(string) ] ;
-
- # drop trailing "ing"
+
+ # Drop trailing "ing".
local s2 = [ MATCH ^(.*)ing$ : $(s1[2]) ] ;
s2 ?= $(s1[2]) ;
-
- # Reduce all doubled characters to one
+
+ # Reduce all doubled characters to one.
local last = "" ;
for local c in [ chars $(s2) ]
{
@@ -86,38 +91,40 @@
}
}
s2 = $(r:J="") ;
-
- # Chop all vowels out of the remainder
+
+ # Chop all vowels out of the remainder.
s2 = [ regex.replace $(s2) [AEIOUaeiou] "" ] ;
- # Shorten remaining consonants to 4 characters
+ # Shorten remaining consonants to 4 characters.
s2 = [ MATCH ^(.?.?.?.?) : $(s2) ] ;
-
- # Glue the initial character back on to the front
+
+ # Glue the initial character back on to the front.
s2 = $(s1[1])$(s2) ;
-
- $(.abbreviated-$(string)) = $(s2) ;
+
+ .abbreviated-$(string) = $(s2) ;
return $(s2) ;
}
}
-# Concatenates the given strings, inserting the given separator
-# between each string.
+
+# Concatenates the given strings, inserting the given separator between each
+# string.
#
rule join (
- strings * # The strings to join.
- : separator ? # The optional separator.
+ strings * # The strings to join.
+ : separator ? # The optional separator.
)
{
separator ?= "" ;
return $(strings:J=$(separator)) ;
}
+
# Split a string into whitespace separated words.
#
rule words (
- string # The string to split.
- : whitespace * # Optional, characters to consider as whitespace.
+ string # The string to split.
+ : whitespace * # Optional, characters to consider as whitespace.
)
{
whitespace = $(whitespace:J="") ;
@@ -135,10 +142,11 @@
return $(w) ;
}
+
# Check that the given string is composed entirely of whitespace.
#
rule is-whitespace (
- string ? # The string to test.
+ string ? # The string to test.
)
{
if ! $(string) { return true ; }
@@ -151,7 +159,7 @@
{
import assert ;
assert.result a b c : chars abc ;
-
+
assert.result rntm : abbreviate runtime ;
assert.result ovrld : abbreviate overload ;
assert.result dbg : abbreviate debugging ;
@@ -160,20 +168,20 @@
assert.result aaa : abbreviate aaa ;
assert.result qck : abbreviate quack ;
assert.result sttc : abbreviate static ;
-
- # check boundary cases
+
+ # Check boundary cases.
assert.result a : chars a ;
assert.result : chars "" ;
assert.result a b c d e f g h : chars abcdefgh ;
assert.result a b c d e f g h i : chars abcdefghi ;
assert.result a b c d e f g h i j : chars abcdefghij ;
assert.result a b c d e f g h i j k : chars abcdefghijk ;
-
+
assert.result a//b/c/d : join a "" b c d : / ;
assert.result abcd : join a "" b c d ;
-
+
assert.result a b c : words "a b c" ;
-
+
assert.true is-whitespace " " ;
assert.false is-whitespace " a b c " ;
assert.true is-whitespace "" ;
Modified: branches/release/tools/build/v2/util/utility.jam
==============================================================================
--- branches/release/tools/build/v2/util/utility.jam (original)
+++ branches/release/tools/build/v2/util/utility.jam 2008-07-15 09:53:41 EDT (Tue, 15 Jul 2008)
@@ -108,7 +108,7 @@
-local rule __test__ ( )
+rule __test__ ( )
{
import assert ;
import "class" : new ;
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk