From ddc88906c1b835bd66e8021dfdadb423ecf23e71 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Thu, 16 Oct 2008 08:42:03 +0000 Subject: [PATCH] Wholesale Boost.Build merge from the trunk [SVN r49353] --- v2/build-system.jam | 46 +- v2/build/alias.jam | 18 +- v2/build/build-request.jam | 47 +- v2/build/feature.jam | 12 +- v2/build/generators.jam | 493 +++--- v2/build/project.jam | 126 +- v2/build/property-set.jam | 12 +- v2/build/property.jam | 49 +- v2/build/targets.jam | 120 +- v2/build/toolset.jam | 46 +- v2/build/type.jam | 112 +- v2/build/virtual-target.jam | 123 +- v2/contrib/wxFormBuilder.jam | 195 +++ v2/doc/{Jamfile.v2 => jamfile.jam} | 0 v2/doc/src/advanced.xml | 441 +++--- v2/doc/src/faq.xml | 550 ++++--- v2/doc/src/reference.xml | 87 +- v2/doc/src/tasks.xml | 929 +++++------ .../customization/{Jamfile => jamfile.jam} | 0 .../{project-root.jam => jamroot.jam} | 0 v2/example/customization/readme.txt | 10 +- v2/example/customization/usage.verbatim | 5 +- v2/example/generate/REAME.txt | 20 +- v2/example/generate/{Jamroot => jamroot.jam} | 0 v2/example/generator/README.txt | 7 +- v2/example/generator/{Jamroot => jamroot.jam} | 0 v2/example/gettext/{Jamfile => jamfile.jam} | 0 .../gettext/{project-root.jam => jamroot.jam} | 0 v2/example/gettext/readme.txt | 13 +- v2/example/hello/{Jamroot => jamroot.jam} | 1 - v2/example/hello/readme.txt | 7 + .../libraries/app/{Jamfile => jamfile.jam} | 0 v2/example/libraries/{Jamroot => jamroot.jam} | 0 .../util/foo/{Jamfile => jamfile.jam} | 0 v2/example/make/Jamroot | 23 - v2/example/make/foo.py | 2 + v2/example/make/jamroot.jam | 10 + v2/example/make/main_cpp.pro | 3 +- v2/example/make/readme.txt | 10 +- v2/example/pch/{Jamroot => jamroot.jam} | 0 .../python_modules/{Jamroot => jamroot.jam} | 0 v2/example/python_modules/readme.txt | 15 +- v2/example/qt/README.txt | 15 +- .../qt/qt3/hello/{Jamroot => jamroot.jam} | 0 .../qt3/moccable-cpp/{Jamroot => jamroot.jam} | 0 .../qt/qt3/uic/{Jamroot => jamroot.jam} | 0 .../qt/qt4/hello/{Jamroot => jamroot.jam} | 0 .../qt4/moccable-cpp/{Jamroot => jamroot.jam} | 0 .../qt/qt4/uic/{Jamroot => jamroot.jam} | 0 v2/example/variant/Jamfile | 13 - v2/example/variant/jamfile.jam | 11 + .../variant/{project-root.jam => jamroot.jam} | 0 .../variant/libs/{Jamfile => jamfile.jam} | 0 v2/example/variant/readme.txt | 16 +- .../{project-root.jam => jamroot.jam} | 0 v2/generators_prototype.py | 731 --------- v2/index.html | 2 +- v2/kernel/modules.jam | 2 + v2/nightly.sh | 2 +- v2/roll.sh | 6 +- v2/test/BoostBuild.py | 67 +- v2/test/abs_workdir.py | 10 +- v2/test/absolute_sources.py | 64 +- v2/test/alias.py | 21 +- v2/test/alternatives.py | 79 +- v2/test/bad_dirname.py | 19 +- v2/test/boostbook.py | 12 +- v2/test/boostbook/{Jamroot => jamroot.jam} | 0 v2/test/build_dir.py | 90 +- v2/test/build_file.py | 42 +- v2/test/build_no.py | 27 +- v2/test/c_file.py | 22 +- v2/test/chain.py | 36 +- v2/test/clean.py | 50 +- v2/test/composite.py | 18 +- v2/test/conditionals.py | 8 +- v2/test/conditionals2.py | 8 +- v2/test/conditionals3.py | 8 +- v2/test/conditionals_multiple.py | 7 +- v2/test/configuration.py | 5 +- v2/test/core_d12.py | 15 +- v2/test/core_delete_module.py | 12 +- v2/test/core_dependencies.py | 71 +- v2/test/core_import_module.py | 29 +- v2/test/core_modifiers.py | 27 +- v2/test/core_varnames.py | 9 +- v2/test/custom_generator.py | 28 +- v2/test/default_build.py | 64 +- v2/test/default_features.py | 34 +- v2/test/default_toolset.py | 6 +- .../dependency-test/{Jamfile => jamfile.jam} | 0 .../{project-root.jam => jamroot.jam} | 0 v2/test/dependency_property.py | 27 +- v2/test/dependency_test.py | 53 +- .../{Jamfile => jamfile.jam} | 0 .../{Jamfile2 => jamfile2.jam} | 0 .../{project-root.jam => jamroot.jam} | 0 v2/test/direct_request_test.py | 44 +- v2/test/disambiguation.py | 31 +- v2/test/dll_path.py | 83 +- v2/test/double_loading.py | 19 +- v2/test/duplicate.py | 37 +- v2/test/example_customization.py | 18 +- v2/test/example_gettext.py | 17 +- v2/test/example_libraries.py | 17 +- v2/test/example_make.py | 20 +- v2/test/example_qt4.py | 6 +- v2/test/expansion.py | 65 +- v2/test/explicit.py | 38 +- v2/test/file_name_handling.py | 5 +- v2/test/free_features_request.py | 29 +- v2/test/gcc_runtime.py | 24 +- v2/test/generator_selection.py | 110 ++ .../generators-test/{Jamfile => jamfile.jam} | 0 .../{project-root.jam => jamroot.jam} | 0 .../lib/{Jamfile => jamfile.jam} | 0 v2/test/generators_test.py | 35 +- v2/test/implicit_dependency.py | 30 +- v2/test/indirect_conditional.py | 34 +- v2/test/inherit_toolset.py | 67 +- v2/test/inherited_dependency.py | 237 +++ v2/test/inline.py | 42 +- v2/test/{Jamfile => jamfile.jam} | 0 v2/test/lib_source_property.py | 30 +- v2/test/library_chain.py | 101 +- v2/test/library_order.py | 80 +- v2/test/library_property.py | 42 +- v2/test/load_dir.py | 29 +- v2/test/load_order.py | 55 +- v2/test/loop.py | 25 +- v2/test/m1-01.py | 28 +- v2/test/m1-02.py | 44 +- v2/test/m1-03.py | 20 +- v2/test/make_rule.py | 46 +- v2/test/module_actions.py | 2 +- v2/test/ndebug.py | 39 +- v2/test/no_type.py | 15 +- v2/test/notfile.py | 30 +- v2/test/ordered_include.py | 41 + v2/test/ordered_properties.py | 38 +- v2/test/out_of_tree.py | 41 +- v2/test/path_features.py | 40 +- v2/test/pch.py | 69 +- v2/test/prebuilt.py | 38 +- v2/test/prebuilt/ext/{Jamfile => jamfile.jam} | 0 .../prebuilt/ext/{Jamfile2 => jamfile2.jam} | 0 .../prebuilt/ext/{Jamfile3 => jamfile3.jam} | 0 .../ext/{project-root.jam => jamroot.jam} | 0 v2/test/prebuilt/{Jamfile => jamfile.jam} | 0 .../{project-root.jam => jamroot.jam} | 0 v2/test/print.py | 13 +- .../dir/{Jamfile => jamfile.jam} | 0 .../dir2/{Jamfile => jamfile.jam} | 0 .../dir2/{project-root.jam => jamroot.jam} | 0 .../project-test1/{Jamfile => jamfile.jam} | 0 .../{project-root.jam => jamroot.jam} | 0 .../project-test3/{Jamfile => jamfile.jam} | 0 .../{project-root.jam => jamroot.jam} | 0 .../lib/{Jamfile => jamfile.jam} | 0 .../lib2/helper/{Jamfile => jamfile.jam} | 0 .../lib2/{Jamfile => jamfile.jam} | 0 .../lib3/{Jamfile => jamfile.jam} | 0 .../lib3/{project-root.jam => jamroot.jam} | 0 .../project-test4/{Jamfile => jamfile.jam} | 0 .../project-test4/{Jamfile3 => jamfile3.jam} | 0 .../project-test4/{Jamfile4 => jamfile4.jam} | 0 .../project-test4/{Jamfile5 => jamfile5.jam} | 0 .../{project-root.jam => jamroot.jam} | 0 .../lib/{Jamfile => jamfile.jam} | 0 .../lib/{Jamfile1 => jamfile1.jam} | 0 .../lib/{Jamfile2 => jamfile2.jam} | 0 .../lib/{Jamfile3 => jamfile3.jam} | 0 .../lib2/{Jamfile => jamfile.jam} | 0 .../lib2/{Jamfile2 => jamfile2.jam} | 0 v2/test/project_dependencies.py | 44 +- v2/test/project_glob.py | 125 +- v2/test/project_root_constants.py | 34 +- v2/test/project_root_rule.py | 36 +- v2/test/project_test1.py | 17 +- v2/test/project_test3.py | 39 +- v2/test/project_test4.py | 29 +- v2/test/property_expansion.py | 19 +- v2/test/qt4.py | 17 +- v2/test/qt4/{Jamroot => jamroot.jam} | 0 v2/test/railsys.py | 10 +- .../libx/{project-root.jam => jamroot.jam} | 0 .../railsys/libx/src/{Jamfile => jamfile.jam} | 0 .../railsys/program/{Jamfile => jamfile.jam} | 0 .../program/{project-root.jam => jamroot.jam} | 0 .../program/liba/{Jamfile => jamfile.jam} | 0 .../program/main/{Jamfile => jamfile.jam} | 0 v2/test/rebuilds.py | 8 +- v2/test/regression.py | 66 +- v2/test/relative_sources.py | 19 +- v2/test/remove_requirement.py | 90 +- v2/test/resolution.py | 33 +- v2/test/searched_lib.py | 109 +- v2/test/skipping.py | 42 +- v2/test/sort_rule.py | 6 +- v2/test/source_locations.py | 35 +- v2/test/stage.py | 157 +- v2/test/standalone.py | 34 +- v2/test/startup_v1.py | 84 +- v2/test/startup_v2.py | 28 +- v2/test/suffix.py | 37 +- v2/test/svn_tree.py | 14 +- v2/test/symlink.py | 41 +- v2/test/tag.py | 24 +- v2/test/template.py | 47 +- v2/test/test1.py | 5 +- v2/test/test2.py | 23 +- v2/test/test2/{Jamfile => jamfile.jam} | 0 v2/test/test_all.py | 180 +-- v2/test/test_result_dumping.py | 33 + v2/test/test_system.html | 19 +- v2/test/testing_primitives.py | 19 +- v2/test/testing_support.py | 61 + v2/test/timedata.py | 121 +- v2/test/tree.py | 18 +- v2/test/unit_test.py | 17 +- v2/test/unit_tests.py | 5 +- v2/test/unused.py | 19 +- v2/test/unused/{Jamfile => jamfile.jam} | 0 .../unused/{project-root.jam => jamroot.jam} | 0 v2/test/use_requirements.py | 258 ++-- v2/test/using.py | 36 +- v2/test/v1-testing/{Jamfile => jamfile.jam} | 0 v2/test/v1_testing.py | 30 +- v2/test/v1_testing/{Jamfile => jamfile.jam} | 0 .../{project-root.jam => jamroot.jam} | 0 v2/test/wrapper.py | 40 +- v2/test/wrong_project.py | 31 +- v2/tools/acc.jam | 17 +- v2/tools/boostbook-config.jam | 8 +- v2/tools/builtin.jam | 117 +- v2/tools/cast.jam | 64 +- v2/tools/common.jam | 106 +- v2/tools/cw.jam | 5 +- v2/tools/darwin.jam | 6 +- v2/tools/gcc.jam | 455 +++--- v2/tools/generate.jam | 36 +- v2/tools/hp_cxx.jam | 15 +- v2/tools/intel-win.jam | 111 +- v2/tools/make.jam | 29 +- v2/tools/message.jam | 55 + v2/tools/msvc.jam | 1359 +++++++++-------- v2/tools/package.jam | 119 +- v2/tools/python.jam | 9 +- v2/tools/qcc.jam | 222 +-- v2/tools/stage.jam | 14 +- v2/tools/testing.jam | 289 ++-- v2/tools/types/exe.jam | 8 +- v2/tools/types/lib.jam | 22 +- v2/tools/types/obj.jam | 8 +- v2/tools/vacpp.jam | 2 +- v2/util/doc.jam | 8 +- v2/util/numbers.jam | 69 +- v2/util/option.jam | 42 +- v2/util/path.jam | 65 +- v2/util/regex.jam | 129 +- v2/util/sequence.jam | 4 +- v2/util/utility.jam | 226 ++- 262 files changed, 6651 insertions(+), 6299 deletions(-) create mode 100644 v2/contrib/wxFormBuilder.jam rename v2/doc/{Jamfile.v2 => jamfile.jam} (100%) rename v2/example/customization/{Jamfile => jamfile.jam} (100%) rename v2/example/customization/{project-root.jam => jamroot.jam} (100%) rename v2/example/generate/{Jamroot => jamroot.jam} (100%) rename v2/example/generator/{Jamroot => jamroot.jam} (100%) rename v2/example/gettext/{Jamfile => jamfile.jam} (100%) rename v2/example/gettext/{project-root.jam => jamroot.jam} (100%) rename v2/example/hello/{Jamroot => jamroot.jam} (96%) create mode 100644 v2/example/hello/readme.txt rename v2/example/libraries/app/{Jamfile => jamfile.jam} (100%) rename v2/example/libraries/{Jamroot => jamroot.jam} (100%) rename v2/example/libraries/util/foo/{Jamfile => jamfile.jam} (100%) delete mode 100644 v2/example/make/Jamroot create mode 100644 v2/example/make/foo.py create mode 100644 v2/example/make/jamroot.jam rename v2/example/pch/{Jamroot => jamroot.jam} (100%) rename v2/example/python_modules/{Jamroot => jamroot.jam} (100%) rename v2/example/qt/qt3/hello/{Jamroot => jamroot.jam} (100%) rename v2/example/qt/qt3/moccable-cpp/{Jamroot => jamroot.jam} (100%) rename v2/example/qt/qt3/uic/{Jamroot => jamroot.jam} (100%) rename v2/example/qt/qt4/hello/{Jamroot => jamroot.jam} (100%) rename v2/example/qt/qt4/moccable-cpp/{Jamroot => jamroot.jam} (100%) rename v2/example/qt/qt4/uic/{Jamroot => jamroot.jam} (100%) delete mode 100644 v2/example/variant/Jamfile create mode 100644 v2/example/variant/jamfile.jam rename v2/example/variant/{project-root.jam => jamroot.jam} (100%) rename v2/example/variant/libs/{Jamfile => jamfile.jam} (100%) rename v2/example/versioned/{project-root.jam => jamroot.jam} (100%) delete mode 100644 v2/generators_prototype.py rename v2/test/boostbook/{Jamroot => jamroot.jam} (100%) rename v2/test/dependency-test/{Jamfile => jamfile.jam} (100%) rename v2/test/dependency-test/{project-root.jam => jamroot.jam} (100%) rename v2/test/direct-request-test/{Jamfile => jamfile.jam} (100%) rename v2/test/direct-request-test/{Jamfile2 => jamfile2.jam} (100%) rename v2/test/direct-request-test/{project-root.jam => jamroot.jam} (100%) create mode 100755 v2/test/generator_selection.py rename v2/test/generators-test/{Jamfile => jamfile.jam} (100%) rename v2/test/generators-test/{project-root.jam => jamroot.jam} (100%) rename v2/test/generators-test/lib/{Jamfile => jamfile.jam} (100%) create mode 100755 v2/test/inherited_dependency.py rename v2/test/{Jamfile => jamfile.jam} (100%) create mode 100644 v2/test/ordered_include.py rename v2/test/prebuilt/ext/{Jamfile => jamfile.jam} (100%) rename v2/test/prebuilt/ext/{Jamfile2 => jamfile2.jam} (100%) rename v2/test/prebuilt/ext/{Jamfile3 => jamfile3.jam} (100%) rename v2/test/prebuilt/ext/{project-root.jam => jamroot.jam} (100%) rename v2/test/prebuilt/{Jamfile => jamfile.jam} (100%) rename v2/test/prebuilt/{project-root.jam => jamroot.jam} (100%) rename v2/test/project-test1/dir/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test1/dir2/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test1/dir2/{project-root.jam => jamroot.jam} (100%) rename v2/test/project-test1/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test1/{project-root.jam => jamroot.jam} (100%) rename v2/test/project-test3/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test3/{project-root.jam => jamroot.jam} (100%) rename v2/test/project-test3/lib/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test3/lib2/helper/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test3/lib2/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test3/lib3/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test3/lib3/{project-root.jam => jamroot.jam} (100%) rename v2/test/project-test4/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test4/{Jamfile3 => jamfile3.jam} (100%) rename v2/test/project-test4/{Jamfile4 => jamfile4.jam} (100%) rename v2/test/project-test4/{Jamfile5 => jamfile5.jam} (100%) rename v2/test/project-test4/{project-root.jam => jamroot.jam} (100%) rename v2/test/project-test4/lib/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test4/lib/{Jamfile1 => jamfile1.jam} (100%) rename v2/test/project-test4/lib/{Jamfile2 => jamfile2.jam} (100%) rename v2/test/project-test4/lib/{Jamfile3 => jamfile3.jam} (100%) rename v2/test/project-test4/lib2/{Jamfile => jamfile.jam} (100%) rename v2/test/project-test4/lib2/{Jamfile2 => jamfile2.jam} (100%) rename v2/test/qt4/{Jamroot => jamroot.jam} (100%) rename v2/test/railsys/libx/{project-root.jam => jamroot.jam} (100%) rename v2/test/railsys/libx/src/{Jamfile => jamfile.jam} (100%) rename v2/test/railsys/program/{Jamfile => jamfile.jam} (100%) rename v2/test/railsys/program/{project-root.jam => jamroot.jam} (100%) rename v2/test/railsys/program/liba/{Jamfile => jamfile.jam} (100%) rename v2/test/railsys/program/main/{Jamfile => jamfile.jam} (100%) rename v2/test/test2/{Jamfile => jamfile.jam} (100%) create mode 100755 v2/test/test_result_dumping.py create mode 100755 v2/test/testing_support.py rename v2/test/unused/{Jamfile => jamfile.jam} (100%) rename v2/test/unused/{project-root.jam => jamroot.jam} (100%) rename v2/test/v1-testing/{Jamfile => jamfile.jam} (100%) rename v2/test/v1_testing/{Jamfile => jamfile.jam} (100%) rename v2/test/v1_testing/{project-root.jam => jamroot.jam} (100%) create mode 100644 v2/tools/message.jam diff --git a/v2/build-system.jam b/v2/build-system.jam index e23a3bdc9..313dc31ef 100644 --- a/v2/build-system.jam +++ b/v2/build-system.jam @@ -5,7 +5,7 @@ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) # This file is part of Boost Build version 2. You can think of it as forming the -# the main() routine. It is invoked by the bootstrapping code in bootstrap.jam. +# main() routine. It is invoked by the bootstrapping code in bootstrap.jam. import build-request ; import builtin ; @@ -22,6 +22,7 @@ import regex ; import sequence ; import targets ; import toolset ; +import utility ; import version ; import virtual-target ; @@ -90,8 +91,8 @@ rule command-line-free-features ( ) # Returns the location of the build system. The primary use case is building -# Boost where it's sometimes needed to get the location of other components -# (e.g. BoostBook files) and it's convenient to use locations relative to the +# Boost where it is sometimes needed to get the location of other components +# (e.g. BoostBook files) and it is convenient to use locations relative to the # Boost Build path. # rule location ( ) @@ -138,7 +139,7 @@ local rule actual-clean-targets ( ) local targets-to-clean ; for local t in $(.results-of-main-targets) { - # Don't include roots or sources. + # Do not include roots or sources. targets-to-clean += [ virtual-target.traverse $(t) ] ; } targets-to-clean = [ sequence.unique $(targets-to-clean) ] ; @@ -169,8 +170,8 @@ local rule actual-clean-targets ( ) # Given a target id, try to find and return the corresponding target. This is -# only invoked when there's no Jamfile in ".". This code somewhat duplicates -# code in project-target.find but we can't reuse that code without a +# only invoked when there is no Jamfile in ".". This code somewhat duplicates +# code in project-target.find but we can not reuse that code without a # project-targets instance. # local rule find-target ( target-id ) @@ -305,7 +306,7 @@ local rule load-configuration-files if $(uq) { test-config = $(uq) ; - } + } if $(test-config) { local where = @@ -350,6 +351,9 @@ local rule load-configuration-files local user-config = [ MATCH ^--user-config=(.*)$ : $(.argv) ] ; user-config = $(user-config[-1]) ; user-config ?= [ os.environ BOOST_BUILD_USER_CONFIG ] ; + # Special handling for the case when the OS does not strip the quotes + # around the file name, as is the case when using Cygwin bash. + user-config = [ utility.unquote $(user-config) ] ; local explicitly-requested = $(user-config) ; user-config ?= user-config.jam ; @@ -366,7 +370,8 @@ local rule load-configuration-files if $(.debug-config) { - ECHO "notice: Loading explicitly specified user configuration file:" ; + ECHO "notice: Loading explicitly specified user" + "configuration file:" ; ECHO " $(user-config)" ; } @@ -407,14 +412,14 @@ local rule process-explicit-toolset-requests if $(.debug-config) { - ECHO "notice: [cmdline-cfg] Detected command-line request for" + ECHO notice: [cmdline-cfg] Detected command-line request for $(toolset-version): "toolset=" $(toolset) "version=" $(version) ; } - # If the toolset isn't known, configure it now. + # If the toolset is not known, configure it now. local known ; - if $(toolset) in [ feature.values ] + if $(toolset) in [ feature.values ] { known = true ; } @@ -423,6 +428,14 @@ local rule process-explicit-toolset-requests { known = ; } + # TODO: we should do 'using $(toolset)' in case no version has been + # specified and there are no versions defined for the given toolset to + # allow the toolset to configure its default version. For this we need + # to know how to detect whether a given toolset has any versions + # defined. An alternative would be to do this whenever version is not + # specified but that would require that toolsets correctly handle the + # case when their default version is configured multiple times which + # should be checked for all existing toolsets first. if ! $(known) { @@ -443,13 +456,14 @@ local rule process-explicit-toolset-requests } # Make sure we get an appropriate property into the build request in - # case toolset was specified using the "--toolset=..." command-line + # case toolset has been specified using the "--toolset=..." command-line # option form. if ! $(t) in $(.argv) && ! $(t) in $(feature-toolsets) { if $(.debug-config) { - ECHO notice: [cmdline-cfg] adding toolset=$(t) "to build request." ; + ECHO notice: [cmdline-cfg] adding toolset=$(t) to the build + request. ; } extra-properties += toolset=$(t) ; } @@ -546,7 +560,7 @@ local rule should-clean-project ( project ) ECHO "warning: No toolsets are configured." ; ECHO "warning: Configuring default toolset" \"$(default-toolset)\". ; ECHO "warning: If the default is wrong, your build may not work correctly." ; - ECHO "warning: Use the \"--toolset=xxxxx\" option to override our guess." ; + ECHO "warning: Use the \"toolset=xxxxx\" option to override our guess." ; ECHO "warning: For more configuration options, please consult" ; ECHO "warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html" ; @@ -615,7 +629,7 @@ local rule should-clean-project ( project ) local virtual-targets ; local actual-targets ; - + # Process each target specified on the command-line and convert it into # internal Boost Build target objects. Detect special clean target. If no # main Boost Build targets were explictly requested use the current project @@ -641,7 +655,7 @@ local rule should-clean-project ( project ) if ! $(t) { ECHO "notice: could not find main target" $(id) ; - ECHO "notice: assuming it's a name of file to create." ; + ECHO "notice: assuming it is a name of file to create." ; explicitly-requested-files += $(id) ; } else diff --git a/v2/build/alias.jam b/v2/build/alias.jam index 68b6f923f..48019cb98 100644 --- a/v2/build/alias.jam +++ b/v2/build/alias.jam @@ -33,8 +33,8 @@ class alias-target-class : basic-target rule __init__ ( name : project : sources * : requirements * : default-build * : usage-requirements * ) { - basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements) - : $(default-build) : $(usage-requirements) ; + basic-target.__init__ $(name) : $(project) : $(sources) : + $(requirements) : $(default-build) : $(usage-requirements) ; } rule construct ( name : source-targets * : property-set ) @@ -45,16 +45,16 @@ class alias-target-class : basic-target rule compute-usage-requirements ( subvariant ) { local base = [ basic-target.compute-usage-requirements $(subvariant) ] ; - # Add source's usage requirement. If we don't do this, "alias" does not - # look like a 100% alias. return [ $(base).add [ $(subvariant).sources-usage-requirements ] ] ; } } -# Declares the 'alias' target. It will build sources, and return them unaltered. +# Declares the 'alias' target. It will process its sources virtual-targets by +# returning them unaltered as its own constructed virtual-targets. # -rule alias ( name : sources * : requirements * : default-build * : usage-requirements * ) +rule alias ( name : sources * : requirements * : default-build * : + usage-requirements * ) { local project = [ project.current ] ; @@ -62,8 +62,10 @@ rule alias ( name : sources * : requirements * : default-build * : usage-require [ new alias-target-class $(name) : $(project) : [ targets.main-target-sources $(sources) : $(name) : no-renaming ] : [ targets.main-target-requirements $(requirements) : $(project) ] - : [ targets.main-target-default-build $(default-build) : $(project) ] - : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ] + : [ targets.main-target-default-build $(default-build) : $(project) + ] + : [ targets.main-target-usage-requirements $(usage-requirements) : + $(project) ] ] ; } diff --git a/v2/build/build-request.jam b/v2/build/build-request.jam index e652d669e..8a1f7b0eb 100644 --- a/v2/build/build-request.jam +++ b/v2/build/build-request.jam @@ -13,6 +13,7 @@ import string ; # Transform property-set by applying f to each component property. +# local rule apply-to-property-set ( f property-set ) { local properties = [ feature.split $(property-set) ] ; @@ -20,9 +21,10 @@ local rule apply-to-property-set ( f property-set ) } -# Expand the given build request by combining all property-sets which don't +# Expand the given build request by combining all property-sets which do not # specify conflicting non-free features. Expects all the project files to # already be loaded. +# rule expand-no-defaults ( property-sets * ) { # First make all features and subfeatures explicit. @@ -38,6 +40,7 @@ rule expand-no-defaults ( property-sets * ) # Implementation of x-product, below. Expects all the project files to already # be loaded. +# local rule x-product-aux ( property-sets + ) { local result ; @@ -49,7 +52,7 @@ local rule x-product-aux ( property-sets + ) { local x-product-seen ; { - # Don't mix in any conflicting features. + # Do not mix in any conflicting features. local x-product-used = $(x-product-used) $(f) ; if $(property-sets[2]) @@ -61,8 +64,8 @@ local rule x-product-aux ( property-sets + ) result ?= $(property-sets[1]) ; } - # If we didn't encounter a conflicting feature lower down, don't recurse - # again. + # If we did not encounter a conflicting feature lower down, do not + # recurse again. if ! [ set.intersection $(f) : $(x-product-seen) ] { property-sets = ; @@ -76,7 +79,7 @@ local rule x-product-aux ( property-sets + ) result += [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ; } - # Note that we've seen these features so that higher levels will recurse + # Note that we have seen these features so that higher levels will recurse # again without them set. x-product-seen += $(f) $(seen) ; return $(result) ; @@ -86,6 +89,7 @@ local rule x-product-aux ( property-sets + ) # Return the cross-product of all elements of property-sets, less any that would # contain conflicting values for single-valued features. Expects all the project # files to already be loaded. +# local rule x-product ( property-sets * ) { if $(property-sets).non-empty @@ -101,6 +105,7 @@ local rule x-product ( property-sets * ) # Returns true if either 'v' or the part of 'v' before the first '-' symbol is # an implicit value. Expects all the project files to already be loaded. +# local rule looks-like-implicit-value ( v ) { if [ feature.is-implicit-value $(v) ] @@ -123,6 +128,7 @@ local rule looks-like-implicit-value ( v ) # "vector" means container.jam's "vector"). First is the set of targets # specified in the command line, and second is the set of requested build # properties. Expects all the project files to already be loaded. +# rule from-command-line ( command-line * ) { local targets ; @@ -144,8 +150,8 @@ rule from-command-line ( command-line * ) if [ MATCH "(.*=.*)" : $(e) ] || [ looks-like-implicit-value $(e:D=) : $(feature-space) ] { - properties += [ convert-command-line-element $(e) - : $(feature-space) ] ; + properties += [ convert-command-line-element $(e) : + $(feature-space) ] ; } else { @@ -165,25 +171,42 @@ rule from-command-line ( command-line * ) # Converts one element of command line build request specification into internal # form. Expects all the project files to already be loaded. +# local rule convert-command-line-element ( e ) { local result ; local parts = [ regex.split $(e) "/" ] ; - for local p in $(parts) + while $(parts) { + local p = $(parts[1]) ; local m = [ MATCH "([^=]*)=(.*)" : $(p) ] ; local lresult ; + local feature ; + local values ; if $(m) { - local feature = $(m[1]) ; - local values = [ regex.split $(m[2]) "," ] ; + feature = $(m[1]) ; + values = [ regex.split $(m[2]) "," ] ; lresult = <$(feature)>$(values) ; } else { lresult = [ regex.split $(p) "," ] ; } - + + if $(feature) && free in [ feature.attributes $(feature) ] + { + # If we have free feature, then the value is everything + # until the end of the command line token. Slashes in + # the following string are not taked to mean separation + # of properties. Commas are also not interpreted specially. + values = $(values:J=,) ; + values = $(values) $(parts[2-]) ; + values = $(values:J=/) ; + lresult = <$(feature)>$(values) ; + parts = ; + } + if ! [ MATCH (.*-.*) : $(p) ] { # property.validate cannot handle subfeatures, so we avoid the check @@ -202,6 +225,8 @@ local rule convert-command-line-element ( e ) { result = $(result)/$(lresult) ; } + + parts = $(parts[2-]) ; } return $(result) ; diff --git a/v2/build/feature.jam b/v2/build/feature.jam index 1f4571dbc..f2960a5ef 100644 --- a/v2/build/feature.jam +++ b/v2/build/feature.jam @@ -357,7 +357,8 @@ local rule expand-subfeatures-aux ( local subvalue = $(subvalues[1]) ; # Pop the head off of subvalues. subvalues = $(subvalues[2-]) ; - local subfeature = [ find-implied-subfeature $(feature) $(subvalue) : $(value) ] ; + local subfeature = [ find-implied-subfeature $(feature) $(subvalue) : + $(value) ] ; # If no subfeature was found reconstitute the value string and use that. if ! $(subfeature) @@ -433,8 +434,8 @@ local rule extend-feature ( feature : values * ) } if ! $($(feature).values) { - # This is the first value specified for this feature, - # take it as default value + # This is the first value specified for this feature so make it be the + # default. $(feature).default = $(values[1]) ; } $(feature).values += $(values) ; @@ -584,7 +585,7 @@ rule extend ( feature-or-property subfeature ? : values * ) } else { - # If no subfeature was specified, we didn't expect to see a + # If no subfeature was specified, we do not expect to see a # value-string. if $(value-string) { @@ -771,7 +772,8 @@ local rule is-subfeature-of ( parent-property f ) { # The feature has the form , e.g. # . - local feature-value = [ split-top-feature $(specific-subfeature[1]) ] ; + local feature-value = [ split-top-feature $(specific-subfeature[1]) + ] ; if <$(feature-value[1])>$(feature-value[2]) = $(parent-property) { return true ; diff --git a/v2/build/generators.jam b/v2/build/generators.jam index 77fd423ad..0df66fc3d 100644 --- a/v2/build/generators.jam +++ b/v2/build/generators.jam @@ -36,12 +36,19 @@ # 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. +# +# In order for the system to be able to use a specific generator instance 'when +# needed', the instance needs to be registered with the system using +# generators.register() or one of its related rules. Unregistered generators may +# only be run explicitly and will not be considered by Boost.Build when when +# converting between given target types. import "class" : new ; import errors ; import property-set ; import sequence ; import set ; +import type ; import utility ; import virtual-target ; @@ -52,8 +59,76 @@ if "--debug-generators" in [ modules.peek : ARGV ] } +# Updated cached viable source target type information as needed after a new +# target type gets defined. This is needed because if a target type is a viable +# source target type for some generator then all of the target type's derived +# target types should automatically be considered as viable source target types +# for the same generator as well. Does nothing if a non-derived target type is +# passed to it. +# +rule update-cached-information-with-a-new-type ( type ) +{ + local base-type = [ type.base $(type) ] ; + if $(base-type) + { + for local g in $(.vstg-cached-generators) + { + if $(base-type) in $(.vstg.$(g)) + { + .vstg.$(g) += $(type) ; + } + } + + for local t in $(.vst-cached-types) + { + if $(base-type) in $(.vst.$(t)) + { + .vst.$(t) += $(type) ; + } + } + } +} + + +# Clears cached viable source target type information except for target types +# and generators with all source types listed as viable. Should be called when +# something invalidates those cached values by possibly causing some new source +# types to become viable. +# +local rule invalidate-extendable-viable-source-target-type-cache ( ) +{ + local generators-with-cached-source-types = $(.vstg-cached-generators) ; + .vstg-cached-generators = ; + for local g in $(generators-with-cached-source-types) + { + if $(.vstg.$(g)) = * + { + .vstg-cached-generators += $(g) ; + } + else + { + .vstg.$(g) = ; + } + } + + local types-with-cached-source-types = $(.vst-cached-types) ; + .vst-cached-types = ; + for local t in $(types-with-cached-source-types) + { + if $(.vst.$(t)) = * + { + .vst-cached-types += $(t) ; + } + else + { + .vst.$(t) = ; + } + } +} + + # Outputs a debug message if generators debugging is on. Each element of -# 'message' is checked to see if it's class instance. If so, instead of the +# 'message' is checked to see if it is a class instance. If so, instead of the # value, the result of 'str' call is output. # local rule generators.dout ( message * ) @@ -83,18 +158,8 @@ local rule decrease-indent ( ) } -# 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. +# Models a generator. # -rule normalize-target-list ( targets ) -{ - local v = [ $(targets).get ] ; - $(targets).set $(v[1]) [ sequence.insertion-sort $(v[2-]) : utility.less ] ; -} - - -# Creates a generator class generator { import generators : indent increase-indent decrease-indent generators.dout ; @@ -108,7 +173,8 @@ class generator import "class" : new ; import property ; - EXPORT class@generator : indent increase-indent decrease-indent generators.dout ; + EXPORT class@generator : indent increase-indent decrease-indent + generators.dout ; rule __init__ ( id # Identifies the generator - should be name @@ -146,9 +212,9 @@ class generator { # Create three parallel lists: one with the list of target types, # and two other with prefixes and postfixes to be added to target - # name. We use parallel lists for prefix and postfix (as opposed - # to mapping), because given target type might occur several times, - # for example "H H(%_symbols)". + # name. We use parallel lists for prefix and postfix (as opposed to + # mapping), because given target type might occur several times, for + # example "H H(%_symbols)". local m = [ MATCH ([^\\(]*)(\\((.*)%(.*)\\))? : $(e) ] ; self.target-types += $(m[1]) ; self.name-prefix += $(m[3]:E="") ; @@ -160,7 +226,7 @@ class generator sequence.transform type.validate : $(self.target-types) ; } - ############## End of constructor ################# + ################# End of constructor ################# rule id ( ) { @@ -175,8 +241,8 @@ class generator } # 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. + # assumed to be always the same -- i.e. it can not change depending on some + # provided list of sources. # rule target-types ( ) { @@ -187,6 +253,7 @@ class generator # 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 ( ) @@ -199,7 +266,7 @@ class generator # rule match-rank ( property-set-to-match ) { - # See if generator's requirements are satisfied by 'properties'. Treat a + # See if generator 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 ] ; @@ -218,8 +285,8 @@ class generator } local properties-to-match = [ $(property-set-to-match).raw ] ; - if $(property-requirements) in $(properties-to-match) - && $(feature-requirements) in $(properties-to-match:G) + if $(property-requirements) in $(properties-to-match) && + $(feature-requirements) in $(properties-to-match:G) { return true ; } @@ -235,14 +302,12 @@ class generator # rule clone ( new-id : new-toolset-properties + ) { - return [ new $(__class__) $(new-id) $(self.composing) - : $(self.source-types) - : $(self.target-types-and-names) - # Note: this does not remove any subfeatures of - # which might cause problems - : [ property.change $(self.requirements) : ] - $(new-toolset-properties) - ] ; + return [ new $(__class__) $(new-id) $(self.composing) : + $(self.source-types) : $(self.target-types-and-names) : + # Note: this does not remove any subfeatures of which + # might cause problems. + [ property.change $(self.requirements) : ] + $(new-toolset-properties) ] ; } # Creates another generator that is the same as $(self), except that if @@ -265,23 +330,24 @@ class generator } } - return [ new $(__class__) $(self.id) $(self.composing) - : $(self.source-types) - : $(target-types) - : $(self.requirements) - ] ; + return [ new $(__class__) $(self.id) $(self.composing) : + $(self.source-types) : $(target-types) : $(self.requirements) ] ; } # Tries to invoke this generator on the given sources. Returns a list of - # generated targets (instances of 'virtual-target'). Returning nothing from - # run indicates that the generator was unable to create the target. + # generated targets (instances of 'virtual-target') and optionally a set of + # properties to be added to the usage-requirements for all the generated + # targets. Returning nothing from 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. - : property-set # Desired properties for generated targets. - : sources + # Source targets. - ) + rule run + ( + project # Project for which the targets are generated. + name ? # Used when determining the 'name' attribute for all + # generated targets. See the 'generated-targets' method. + : property-set # Desired properties for generated targets. + : sources + # Source targets. + ) { generators.dout [ indent ] " ** generator" $(self.id) ; generators.dout [ indent ] " composing:" $(self.composing) ; @@ -291,7 +357,7 @@ class generator errors.error "Unsupported source/source-type combination" ; } - # We don't run composing generators if no name is specified. The reason + # We do not run composing generators if no name is specified. The reason # is that composing generator combines several targets, which can have # different names, and it cannot decide which name to give for produced # target. Therefore, the name must be passed. @@ -300,7 +366,7 @@ class generator # the top-level of a transformation graph, or if their name is passed # explicitly. Thus, we dissallow composing generators in the middle. For # example, the transformation CPP -> OBJ -> STATIC_LIB -> RSP -> EXE - # won't be allowed (the OBJ -> STATIC_LIB generator is composing) + # will not be allowed as the OBJ -> STATIC_LIB generator is composing. if ! $(self.composing) || $(name) { run-really $(project) $(name) : $(property-set) : $(sources) ; @@ -311,7 +377,7 @@ class generator { # Targets that this generator will consume directly. local consumed = ; - # Targets that can't be consumed and will be returned as-is. + # Targets that can not be consumed and will be returned as-is. local bypassed = ; if $(self.composing) @@ -328,8 +394,8 @@ class generator local result ; if $(consumed) { - result = [ construct-result $(consumed) : $(project) $(name) - : $(property-set) ] ; + result = [ construct-result $(consumed) : $(project) $(name) : + $(property-set) ] ; } if $(result) @@ -346,14 +412,20 @@ class generator # Constructs the dependency graph to be returned by this generator. # - 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]). + rule construct-result + ( + consumed + # Already prepared list of consumable targets. + # Composing generators may receive multiple sources + # all of which will have types matching those in + # $(self.source-types). Non-composing generators with + # multiple $(self.source-types) will receive exactly + # len $(self.source-types) sources with types matching + # those in $(self.source-types). And non-composing + # generators with only a single source type may + # receive multiple sources with all of them of the + # type listed in $(self.source-types). : project name ? - : property-set # Properties to be used for all actions create here. + : property-set # Properties to be used for all actions created here. ) { local result ; @@ -363,16 +435,14 @@ class generator { for local r in $(consumed) { - result += [ generated-targets $(r) : $(property-set) : $(project) $(name) ] ; #(targets) ; + result += [ generated-targets $(r) : $(property-set) : + $(project) $(name) ] ; } } - else + else if $(consumed) { - if $(consumed) - { - result += [ generated-targets $(consumed) : $(property-set) - : $(project) $(name) ] ; - } + result += [ generated-targets $(consumed) : $(property-set) : + $(project) $(name) ] ; } return $(result) ; } @@ -383,11 +453,11 @@ class generator { # 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 + # - using source file like a.host.cpp, or + # - a type whose 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 + # second case -- not sure, but for now take the part up to the last dot # too. name = [ utility.basename [ $(sources[1]).name ] ] ; @@ -410,11 +480,11 @@ class generator # will be the list of virtual-target, which has the same length as the # 'target-types' attribute and with corresponding types. # - # When 'name' is empty, all source targets must have the same value of the - # 'name' attribute, which will be used instead of the 'name' argument. + # When 'name' is empty, all source targets must have the same 'name' + # attribute value, which will be used instead of the 'name' argument. # - # The value of 'name' attribute for each generated target will be equal to - # the 'name' parameter if there's no name pattern for this type. Otherwise, + # The 'name' attribute value for each generated target will be equal to + # the 'name' parameter if there is no name pattern for this type. Otherwise, # the '%' symbol in the name pattern will be replaced with the 'name' # parameter to obtain the 'name' attribute. # @@ -424,8 +494,8 @@ class generator # determines the basename of a file. # # Note that this pattern mechanism has nothing to do with implicit patterns - # in make. It is a way to produce target which name is different for name of - # source. + # in make. It is a way to produce a target whose name is different than the + # name of its source. # rule generated-targets ( sources + : property-set : project name ? ) { @@ -434,7 +504,7 @@ class generator name = [ determine-output-name $(sources) ] ; } - # Assign an action for each target + # Assign an action for each target. local action = [ action-class ] ; local a = [ class.new $(action) $(sources) : $(self.id) : $(property-set) ] ; @@ -456,30 +526,33 @@ class generator 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 'sources' to targets of types that this generator can + # handle. The intention is to produce the set of targets that can be used + # when the generator is run. # - rule convert-to-consumable-types ( project name ? : - property-set : sources + - : only-one ? # Convert 'source' to only one of the source types. If - # there's more that one possibility, report an error. - : consumed-var # Name of the variable which recieves all targets which - # can be consumed. - bypassed-var # Name of the variable which recieves all targets which - # cannot be consumed + rule convert-to-consumable-types + ( + project name ? + : property-set + : sources + + : only-one ? # Convert 'source' to only one of the source types. If + # there is more that one possibility, report an error. + : consumed-var # Name of the variable which receives all targets which + # can be consumed. + bypassed-var # Name of the variable which receives all targets which + # can not be consumed. ) { - # We're likely to be passed 'consumed' and 'bypassed' var names. Use "_" - # to avoid name conflicts. + # We are 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 + # Do not know how to handle several sources yet. Just try to pass + # the request to other generator. missing-types = $(self.source-types) ; } else @@ -502,11 +575,11 @@ class generator if $(missing-types) { local transformed = [ generators.construct-types $(project) $(name) - : $(missing-types) : $(property-set) : $(sources) ] ; + : $(missing-types) : $(property-set) : $(sources) ] ; # Add targets of right type to 'consumed'. Add others to 'bypassed'. # The 'generators.construct' rule has done its best to convert - # everything to the required type. There's no need to rerun it on + # everything to the required type. There is no need to rerun it on # targets of different types. # NOTE: ignoring usage requirements. @@ -533,12 +606,12 @@ class generator # 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. + # up the call stack do not 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 - # action name, and 'virtual-target.register' won't allow two different - # instances. Therefore, it's OK to use 'set.difference'. + # action name, and 'virtual-target.register' will not allow two + # different instances. Therefore, it is OK to use 'set.difference'. _bypassed = [ set.difference $(_bypassed) : $(_consumed) ] ; @@ -546,10 +619,11 @@ class generator $(bypassed-var) += $(_bypassed) ; } - # Converts several files to consumable types. + # Converts several files to consumable types. Called for composing + # generators only. # - rule convert-multiple-sources-to-consumable-types - ( project : property-set : sources * : consumed-var bypassed-var ) + 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. @@ -558,8 +632,8 @@ class generator local _c ; local _b ; # TODO: need to check for failure on each source. - convert-to-consumable-types $(project) : $(property-set) - : $(source) : true : _c _b ; + convert-to-consumable-types $(project) : $(property-set) : $(source) + : true : _c _b ; if ! $(_c) { generators.dout [ indent ] " failed to convert " $(source) ; @@ -579,15 +653,15 @@ class generator for local st in $(source-types) { - # The 'source' if of right type already) - if $(real-source-type) = $(st) || - [ type.is-derived $(real-source-type) $(st) ] + # The 'source' if of the right type already. + if $(real-source-type) = $(st) || [ type.is-derived + $(real-source-type) $(st) ] { $(consumed-var) += $(source) ; } else { - $(missing-types-var) += $(st) ; + $(missing-types-var) += $(st) ; } } } @@ -602,33 +676,28 @@ class generator } -.generators = ; - - # Registers a new generator instance 'g'. # rule register ( g ) { - .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. + # occurrence of that generator in .generators.$(t) in that case, otherwise, + # it will be tried twice and we will get a false ambiguity. for local t in [ sequence.unique [ $(g).target-types ] ] { .generators.$(t) += $(g) ; } - # Update the set of generators for toolset + # 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. 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 + # Some generators have multiple periods in their name, so a simple $(id:S=) + # will not 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. @@ -638,35 +707,60 @@ rule register ( g ) base = $(base:B) ; } .generators-for-toolset.$(base) += $(g) ; + + + # After adding a new generator that can construct new target types, we need + # to clear the related cached viable source target type information for + # constructing a specific target type or using a specific generator. Cached + # viable source target type lists affected by this are those containing any + # of the target types constructed by the new generator or any of their base + # target types. + # + # A more advanced alternative to clearing that cached viable source target + # type information would be to expand it with additional source types or + # even better - mark it as needing to be expanded on next use. + # + # Also see the http://thread.gmane.org/gmane.comp.lib.boost.build/19077 + # mailing list thread for an even more advanced idea of how we could convert + # Boost Build's Jamfile processing, target selection and generator selection + # into separate steps which would prevent these caches from ever being + # invalidated. + # + # For now we just clear all the cached viable source target type information + # that does not simply state 'all types' and may implement a more detailed + # algorithm later on if it becomes needed. + + invalidate-extendable-viable-source-target-type-cache ; } -# Creates new instance of the 'generator' class and registers it. Returns the -# created instance. Rationale: the instance is returned so that it's possible to -# first register a generator and then call the 'run' method on that generator, -# bypassing all generator selection. +# Creates a new non-composing 'generator' class instance and registers it. +# Returns the created instance. Rationale: the instance is returned so that it +# is possible to first register a generator and then call its 'run' method, +# bypassing the whole generator selection process. # rule register-standard ( id : source-types * : target-types + : requirements * ) { - local g = [ new generator $(id) : $(source-types) : $(target-types) - : $(requirements) ] ; + local g = [ new generator $(id) : $(source-types) : $(target-types) : + $(requirements) ] ; register $(g) ; return $(g) ; } -# Creates new instance of the 'composing-generator' class and registers it. +# Creates a new composing 'generator' class instance and registers it. # -rule register-composing ( id : source-types * : target-types + : requirements * ) +rule register-composing ( id : source-types * : target-types + : requirements * + ) { - local g = [ new generator $(id) true : $(source-types) : $(target-types) - : $(requirements) ] ; + local g = [ new generator $(id) true : $(source-types) : $(target-types) : + $(requirements) ] ; register $(g) ; return $(g) ; } -# Returns all generators which belong to 'toolset', i.e. whose ids are +# Returns all generators belonging to the given 'toolset', i.e. whose ids are # '$(toolset).'. # rule generators-for-toolset ( toolset ) @@ -677,11 +771,11 @@ rule generators-for-toolset ( toolset ) # Make generator 'overrider-id' be preferred to 'overridee-id'. If, when # searching for generators that could produce a target of a certain type, both -# those generators are amoung viable generators, the overridden generator is +# those generators are among viable generators, the overridden generator is # immediately discarded. # # The overridden generators are discarded immediately after computing the list -# of viable generators, before running any of them. +# of viable generators but before running any of them. # rule override ( overrider-id : overridee-id ) { @@ -689,30 +783,34 @@ rule override ( overrider-id : overridee-id ) } -# Set if results of the current generators search are going to be cached. This -# means no futher attempts to cache generators search should be made. -.caching = ; - - # Returns a list of source type which can possibly be converted to 'target-type' # by some chain of generator invocation. # -# More formally, takes all generators for 'target-type' and returns union of -# source types for those generators and result of calling itself recirsively on +# More formally, takes all generators for 'target-type' and returns a union of +# source types for those generators and result of calling itself recursively on # source types. # +# Returns '*' in case any type should be considered a viable source type for the +# given type. +# local rule viable-source-types-real ( target-type ) { - local generators ; - - local t = [ type.all-bases $(target-type) ] ; - local result ; - # 't' is the list of types which have not yet been processed. + + # 't0' is the initial list of target types we need to process to get a list + # of their viable source target types. New target types will not be added to + # this list. + local t0 = [ type.all-bases $(target-type) ] ; + + # 't' is the list of target types which have not yet been processed to get a + # list of their viable source target types. This list will get expanded as + # we locate more target types to process. + local t = $(t0) ; + while $(t) { - # Find all generators for current type. Unlike 'find-viable-generators' - # we don't care about property-set. + # Find all generators for the current type. Unlike + # 'find-viable-generators' we do not care about the property-set. local generators = $(.generators.$(t[1])) ; t = $(t[2-]) ; @@ -723,11 +821,11 @@ local rule viable-source-types-real ( target-type ) if ! [ $(g).source-types ] { - # Empty source types -- everything can be accepted + # Empty source types -- everything can be accepted. result = * ; # This will terminate this loop. generators = ; - # This will terminate outer loop. + # This will terminate the outer loop. t = ; } @@ -735,14 +833,25 @@ local rule viable-source-types-real ( target-type ) { if ! $(source-type) in $(result) { - # If generator accepts 'source-type' it - # will happily accept any type derived from it - local all = [ type.all-derived $(source-type) ] ; - for local n in $(all) + # If a generator accepts a 'source-type' it will also + # happily accept any type derived from it. + for local n in [ type.all-derived $(source-type) ] { if ! $(n) in $(result) { - t += $(n) ; + # Here there is no point in adding target types to + # the list of types to process in case they are or + # have already been on that list. We optimize this + # check by realizing that we only need to avoid the + # original target type's base types. Other target + # types that are or have been on the list of target + # types to process have been added to the 'result' + # list as well and have thus already been eliminated + # by the previous if. + if ! $(n) in $(t0) + { + t += $(n) ; + } result += $(n) ; } } @@ -751,7 +860,7 @@ local rule viable-source-types-real ( target-type ) } } - return [ sequence.unique $(result) ] ; + return $(result) ; } @@ -762,6 +871,7 @@ rule viable-source-types ( target-type ) local key = .vst.$(target-type) ; if ! $($(key)) { + .vst-cached-types += $(target-type) ; local v = [ viable-source-types-real $(target-type) ] ; if ! $(v) { @@ -781,15 +891,18 @@ rule viable-source-types ( target-type ) # 'generator', has some change of being eventually used (probably after # conversion by other generators). # +# Returns '*' in case any type should be considered a viable source type for the +# given generator. +# rule viable-source-types-for-generator-real ( generator ) { local source-types = [ $(generator).source-types ] ; if ! $(source-types) { - # If generator does not specify any source types, it might be special + # If generator does not specify any source types, it might be a special # generator like builtin.lib-generator which just relays to other # generators. Return '*' to indicate that any source type is possibly - # OK, since we don't know for sure. + # OK, since we do not know for sure. return * ; } else @@ -797,15 +910,18 @@ rule viable-source-types-for-generator-real ( generator ) local result ; for local s in $(source-types) { - result += [ type.all-derived $(s) ] - [ generators.viable-source-types $(s) ] ; + local viable-sources = [ generators.viable-source-types $(s) ] ; + if $(viable-sources) = * + { + result = * ; + source-types = ; # Terminate the loop. + } + else + { + result += [ type.all-derived $(s) ] $(viable-sources) ; + } } - result = [ sequence.unique $(result) ] ; - if * in $(result) - { - result = * ; - } - return $(result) ; + return [ sequence.unique $(result) ] ; } } @@ -817,6 +933,7 @@ local rule viable-source-types-for-generator ( generator ) local key = .vstg.$(generator) ; if ! $($(key)) { + .vstg-cached-generators += $(generator) ; local v = [ viable-source-types-for-generator-real $(generator) ] ; if ! $(v) { @@ -874,8 +991,9 @@ local rule try-one-generator-really ( project name ? : generator : target-type } -# Checks if generator invocation can be pruned, because it's guaranteed to fail. -# If so, quickly returns empty list. Otherwise, calls try-one-generator-really. +# Checks if generator invocation can be pruned, because it is guaranteed to +# fail. If so, quickly returns an empty list. Otherwise, calls +# try-one-generator-really. # local rule try-one-generator ( project name ? : generator : target-type : property-set : sources * ) @@ -885,21 +1003,21 @@ local rule try-one-generator ( project name ? : generator : target-type { source-types += [ $(s).type ] ; } - local viable-source-types = - [ viable-source-types-for-generator $(generator) ] ; + local viable-source-types = [ viable-source-types-for-generator $(generator) + ] ; if $(source-types) && $(viable-source-types) != * && - ! [ set.intersection $(source-types) : $(viable-source-types) ] + ! [ set.intersection $(source-types) : $(viable-source-types) ] { local id = [ $(generator).id ] ; generators.dout [ indent ] " ** generator '$(id)' pruned" ; #generators.dout [ indent ] "source-types" '$(source-types)' ; #generators.dout [ indent ] "viable-source-types" '$(viable-source-types)' ; } - else { - return [ try-one-generator-really $(project) $(name) - : $(generator) - : $(target-type) : $(property-set) : $(sources) ] ; + else + { + return [ try-one-generator-really $(project) $(name) : $(generator) : + $(target-type) : $(property-set) : $(sources) ] ; } } @@ -913,7 +1031,7 @@ rule construct-types ( project name ? : target-types + : property-set for local t in $(target-types) { local r = [ construct $(project) $(name) : $(t) : $(property-set) : - $(sources) ] ; + $(sources) ] ; if $(r) { usage-requirements = [ $(usage-requirements).add $(r[1]) ] ; @@ -955,13 +1073,13 @@ local rule ensure-type ( targets * ) # Returns generators which can be used to construct target of specified type # with specified properties. Uses the following algorithm: # - iterates over requested target-type and all its bases (in the order returned -# by type.all-bases. +# by type.all-bases). # - for each type find all generators that generate that type and whose # requirements are satisfied by properties. # - if the set of generators is not empty, returns that set. # -# Note: this algorithm explicitly ignores generators for base classes if there's -# at least one generator for the requested target-type. +# Note: this algorithm explicitly ignores generators for base classes if there +# is at least one generator for the requested target-type. # local rule find-viable-generators-aux ( target-type : property-set ) { @@ -988,11 +1106,11 @@ local rule find-viable-generators-aux ( target-type : property-set ) if $(t[1]) != $(target-type) { - # We're here, when no generators for target-type are found, but - # there are some generators for a base type. We'll try to use - # them, but they will produce targets of base type, not of - # 'target-type'. So, we clone the generators and modify the list - # of target types. + # We are here because there were no generators found for + # target-type but there are some generators for its base type. + # We will try to use them, but they will produce targets of + # base type, not of 'target-type'. So, we clone the generators + # and modify the list of target types. local generators2 ; for local g in $(generators) { @@ -1001,8 +1119,8 @@ local rule find-viable-generators-aux ( target-type : property-set ) # should work. That list is only used when inheriting a # toolset, which should have been done before running # generators. - generators2 += [ - $(g).clone-and-change-target-type $(t[1]) : $(target-type) ] ; + generators2 += [ $(g).clone-and-change-target-type $(t[1]) : + $(target-type) ] ; generators.register $(generators2[-1]) ; } generators = $(generators2) ; @@ -1059,7 +1177,7 @@ rule find-viable-generators ( target-type : property-set ) # Generators which override 'all'. local all-overrides ; - # Generators which are overriden + # Generators which are overriden. local overriden-ids ; for local g in $(viable-generators) { @@ -1094,10 +1212,11 @@ rule find-viable-generators ( target-type : property-set ) # Attempts to construct a target by finding viable generators, running them and # selecting the dependency graph. # -local rule construct-really ( - project name ? : target-type : property-set : sources * ) +local rule construct-really ( project name ? : target-type : property-set : + sources * ) { - viable-generators = [ find-viable-generators $(target-type) : $(property-set) ] ; + viable-generators = [ find-viable-generators $(target-type) : + $(property-set) ] ; generators.dout [ indent ] "*** " [ sequence.length $(viable-generators) ] " viable generators" ; @@ -1109,8 +1228,8 @@ local rule construct-really ( # This variable will be restored on exit from this scope. local .active-generators = $(g) $(.active-generators) ; - local r = [ try-one-generator $(project) $(name) : $(g) : $(target-type) : - $(property-set) : $(sources) ] ; + local r = [ try-one-generator $(project) $(name) : $(g) : $(target-type) + : $(property-set) : $(sources) ] ; if $(r) { @@ -1152,8 +1271,8 @@ local rule construct-really ( # 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. +# The 'sources' are treated as a collection of *possible* ingridients, i.e. +# there is no obligation 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', @@ -1181,8 +1300,8 @@ rule construct ( project name ? : target-type : property-set * : sources * ) generators.dout [ indent ] " properties:" [ $(property-set).raw ] ; } - local result = [ construct-really $(project) $(name) - : $(target-type) : $(property-set) : $(sources) ] ; + local result = [ construct-really $(project) $(name) : $(target-type) : + $(property-set) : $(sources) ] ; decrease-indent ; diff --git a/v2/build/project.jam b/v2/build/project.jam index f2771f1ec..f154795fa 100644 --- a/v2/build/project.jam +++ b/v2/build/project.jam @@ -103,14 +103,13 @@ JAMROOT ?= project-root.jam [Jj]amroot [Jj]amroot.jam ; # rule load-parent ( location ) { - local found = [ path.glob-in-parents $(location) : - $(JAMROOT) $(JAMFILE) ] ; + local found = [ path.glob-in-parents $(location) : $(JAMROOT) $(JAMFILE) ] ; if ! $(found) { - ECHO "error: Could not find parent for project at '$(location)'" ; - ECHO "error: Did not find Jamfile.jam or Jamroot.jam in any parent directory." ; - EXIT ; + ECHO error: Could not find parent for project at '$(location)' ; + EXIT error: Did not find Jamfile.jam or Jamroot.jam in any parent + directory. ; } return [ load $(found[1]:D) ] ; @@ -153,8 +152,8 @@ rule find ( name : current-location ) if ! $(project-module) { - local location = [ path.root - [ path.make $(name) ] $(current-location) ] ; + local location = [ path.root [ path.make $(name) ] $(current-location) ] + ; # If no project is registered for the given location, try to load it. # First see if we have a Jamfile. If not, then see if we might have a @@ -220,8 +219,8 @@ rule find-jamfile ( { if ! $(.parent-jamfile.$(dir)) { - .parent-jamfile.$(dir) = - [ path.glob-in-parents $(dir) : $(JAMFILE) ] ; + .parent-jamfile.$(dir) = [ path.glob-in-parents $(dir) : $(JAMFILE) + ] ; } jamfile-glob = $(.parent-jamfile.$(dir)) ; } @@ -237,7 +236,7 @@ rule find-jamfile ( local jamfile-to-load = $(jamfile-glob) ; # Multiple Jamfiles found in the same place. Warn about this and ensure we - # use only one of them. As a temporary convenience measure, if there's + # use only one of them. As a temporary convenience measure, if there is # Jamfile.v2 among found files, suppress the warning and use it. # if $(jamfile-to-load[2-]) @@ -262,11 +261,10 @@ rule find-jamfile ( # if ! $(no-errors) && ! $(jamfile-to-load) { - errors.error - "Unable to load Jamfile." : - "Could not find a Jamfile in directory '$(dir)'". : - "Attempted to find it with pattern '"$(JAMFILE:J=" ")"'." : - "Please consult the documentation at 'http://www.boost.org'." ; + errors.error Unable to load Jamfile. + : Could not find a Jamfile in directory '$(dir)'. + : Attempted to find it with pattern '"$(JAMFILE:J=" ")"'. + : Please consult the documentation at 'http://www.boost.org'. ; } return $(jamfile-to-load) ; @@ -319,13 +317,12 @@ local rule load-jamfile ( # Now do some checks. if $(.current-project) != $(saved-project) { - errors.error "The value of the .current-project variable" - : "has magically changed after loading a Jamfile." - : "This means some of the targets might be defined in the wrong project." - : "after loading" $(jamfile-module) - : "expected value" $(saved-project) - : "actual value" $(.current-project) - ; + errors.error "The value of the .current-project variable has magically" + : "changed after loading a Jamfile. This means some of the targets" + : "might be defined in the wrong project." + : "after loading" $(jamfile-module) + : "expected value" $(saved-project) + : "actual value" $(.current-project) ; } if $(.global-build-dir) @@ -578,10 +575,8 @@ class project-attributes if $(result[1]) = "@error" { - errors.error - "Requirements for project at '$(self.location)'" - "conflict with parent's." : - "Explanation: " $(result[2-]) ; + errors.error Requirements for project at '$(self.location)' + conflict with parent's. : Explanation: $(result[2-]) ; } else { @@ -601,7 +596,8 @@ class project-attributes local non-free = [ property.remove free : $(unconditional) ] ; if $(non-free) { - errors.error "usage-requirements" $(specification) "have non-free properties" $(non-free) ; + errors.error usage-requirements $(specification) have non-free + properties $(non-free) ; } local t = [ property.translate-paths $(specification) : $(self.location) ] ; @@ -624,8 +620,8 @@ class project-attributes self.source-location = ; for local src-path in $(specification) { - self.source-location += [ path.root - [ path.make $(src-path) ] $(self.location) ] ; + self.source-location += [ path.root [ path.make $(src-path) ] + $(self.location) ] ; } } else if $(attribute) = "build-dir" @@ -633,11 +629,17 @@ class project-attributes self.build-dir = [ path.root [ path.make $(specification) ] $(self.location) ] ; } - else if ! $(attribute) in "id" "default-build" "location" - "source-location" "parent" "projects-to-build" "project-root" + else if $(attribute) = "id" { - errors.error "Invalid project attribute '$(attribute)' specified" - "for project at '$(self.location)'" ; + id = [ path.root $(specification) / ] ; + project.register-id $(id) : $(self.project-module) ; + self.id = $(id) ; + } + else if ! $(attribute) in "default-build" "location" "parent" + "projects-to-build" "project-root" "source-location" + { + errors.error Invalid project attribute '$(attribute)' specified for + project at '$(self.location)' ; } else { @@ -738,11 +740,11 @@ rule use ( id : location ) { # The project at 'location' either has no id or that id is not equal to # the 'id' parameter. - if $($(id).jamfile-module) - && $($(id).jamfile-module) != $(project-module) + if $($(id).jamfile-module) && ( $($(id).jamfile-module) != + $(project-module) ) { - errors.user-error - "Attempt to redeclare already existing project id '$(id)'" ; + errors.user-error Attempt to redeclare already existing project id + '$(id)' ; } $(id).jamfile-module = $(project-module) ; } @@ -777,12 +779,13 @@ rule extension ( id : options * : * ) # Create the project data, and bring in the project rules into the # module. - project.initialize $(__name__) : - [ path.join [ project.attribute $(root-project) location ] ext $(1:L) ] ; + project.initialize $(__name__) : [ path.join [ project.attribute + $(root-project) location ] ext $(1:L) ] ; # Create the project itself, i.e. the attributes. All extensions are # created in the "/ext" project space. - project /ext/$(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; + project /ext/$(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : + $(9) ; local attributes = [ project.attributes $(__name__) ] ; # Inherit from the root project of whomever is defining us. @@ -797,12 +800,12 @@ rule glob-internal ( project : wildcards + : excludes * : rule-name ) local location = [ $(project).get source-location ] ; local result ; - local paths = [ path.$(rule-name) $(location) - : [ sequence.transform path.make : $(wildcards) ] - : [ sequence.transform path.make : $(excludes) ] ] ; + local paths = [ path.$(rule-name) $(location) : + [ sequence.transform path.make : $(wildcards) ] : + [ sequence.transform path.make : $(excludes) ] ] ; if $(wildcards:D) || $(rule-name) != glob { - # The paths we've found are relative to the current directory, but the + # The paths we have found are relative to the current directory, but the # names specified in the sources list are assumed to be relative to the # source directory of the corresponding project. So, just make the names # absolute. @@ -873,8 +876,6 @@ module project-rules local attributes = [ project.attributes $(__name__) ] ; if $(id) { - id = [ path.root $(id) / ] ; - project.register-id $(id) : $(__name__) ; $(attributes).set id : $(id) ; } @@ -902,19 +903,22 @@ module project-rules local location = [ $(attributes).get location ] ; # Project with an empty location is a 'standalone' project such as # user-config or qt. It has no build dir. If we try to set build dir - # for user-config, we'll then try to inherit it, with either weird - # or wrong consequences. + # for user-config, we shall then try to inherit it, with either + # weird or wrong consequences. if $(location) && $(location) = [ $(attributes).get project-root ] { + # Re-read the project id, since it might have been changed in + # the project's attributes. + id = [ $(attributes).get id ] ; # This is Jamroot. if $(id) { - if $(explicit-build-dir) - && [ path.is-rooted $(explicit-build-dir) ] + if $(explicit-build-dir) && + [ path.is-rooted $(explicit-build-dir) ] { - errors.user-error "Absolute directory specified via 'build-dir' project attribute" - : "Don't know how to combine that with the --build-dir option." - ; + errors.user-error Absolute directory specified via + 'build-dir' project attribute : Do not know how to + combine that with the --build-dir option. ; } # Strip the leading slash from id. local rid = [ MATCH /(.*) : $(id) ] ; @@ -926,11 +930,12 @@ module project-rules } else { - # Not Jamroot + # Not Jamroot. if $(explicit-build-dir) { - errors.user-error "When --build-dir is specified, the 'build-dir' project" - : "attribute is allowed only for top-level 'project' invocations" ; + errors.user-error When --build-dir is specified, the + 'build-dir' project : attribute is allowed only for + top-level 'project' invocations ; } } } @@ -943,7 +948,7 @@ module project-rules rule constant ( name # Variable name of the constant. : value + # Value of the constant. - ) + ) { import project ; local p = [ project.target $(__name__) ] ; @@ -1005,10 +1010,11 @@ module project-rules if $(wildcards:D) || $(excludes:D) { - errors.user-error "The patterns to 'glob-tree' may not include directory" ; + errors.user-error The patterns to 'glob-tree' may not include + directory ; } - return [ project.glob-internal [ project.current ] - : $(wildcards) : $(excludes) : glob-tree ] ; + return [ project.glob-internal [ project.current ] : $(wildcards) : + $(excludes) : glob-tree ] ; } # Calculates conditional requirements for multiple requirements at once. diff --git a/v2/build/property-set.jam b/v2/build/property-set.jam index b3217f0da..cb2e79917 100644 --- a/v2/build/property-set.jam +++ b/v2/build/property-set.jam @@ -5,6 +5,8 @@ import "class" : new ; import feature ; +import path ; +import project ; import property ; import sequence ; import set ; @@ -250,8 +252,8 @@ class property-set { if ! $(self.target-path) { - # The feature can be used to explicitly - # change the location of generated targetsv + # The feature can be used to explicitly change the + # location of generated targets. local l = [ get ] ; if $(l) { @@ -260,7 +262,7 @@ class property-set else { local p = [ as-path ] ; - # Really, an ugly hack. Boost regression test system requires + # A real ugly hack. Boost regression test system requires # specific target paths, and it seems that changing it to handle # other directory layout is really hard. For that reason, we # teach V2 to do the things regression system requires. The @@ -382,6 +384,10 @@ rule create-from-user-input ( raw-properties * : jamfile-module location ) : $(location) ] ; specification = [ property.translate-indirect $(specification) : $(jamfile-module) ] ; + local project-id = [ project.attribute $(jamfile-module) id ] ; + project-id ?= [ path.root $(location) [ path.pwd ] ] ; + specification = [ property.translate-dependencies + $(specification) : $(project-id) : $(location) ] ; specification = [ property.expand-subfeatures-in-conditions $(specification) ] ; specification = [ property.make $(specification) ] ; diff --git a/v2/build/property.jam b/v2/build/property.jam index 92b59673a..5ee66af32 100644 --- a/v2/build/property.jam +++ b/v2/build/property.jam @@ -469,7 +469,8 @@ rule translate-paths ( properties * : path ) # Assumes that all feature values that start with '@' are names of rules, used # 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. +# can be called from other modules. Does nothing for such values that are +# already in the 'indirect-rule' format. # rule translate-indirect ( specification * : context-module ) { @@ -482,7 +483,7 @@ rule translate-indirect ( specification * : context-module ) local v ; if [ MATCH "^([^%]*)%([^%]+)$" : $(m) ] { - # Rule is already in indirect format. + # Rule is already in the 'indirect-rule' format. v = $(m) ; } else @@ -512,6 +513,50 @@ rule translate-indirect ( specification * : context-module ) } +# Binds all dependency properties in a list relative to the given project. +# Targets with absolute paths will be left unchanged and targets which have a +# project specified will have the path to the project interpreted relative to +# the specified location. +# +rule translate-dependencies ( specification * : project-id : location ) +{ + local result ; + for local p in $(specification) + { + local split = [ split-conditional $(p) ] ; + local condition = "" ; + if $(split) + { + condition = $(split[1]): ; + p = $(split[2]) ; + } + if dependency in [ feature.attributes $(p:G) ] + { + local split-target = [ regex.match (.*)//(.*) : $(p:G=) ] ; + if $(split-target) + { + local rooted = [ path.root [ path.make $(split-target[1]) ] + [ path.root $(location) [ path.pwd ] ] ] ; + result += $(condition)$(p:G)$(rooted)//$(split-target[2]) ; + } + else if [ path.is-rooted $(p:G=) ] + { + result += $(condition)$(p) ; + } + else + { + result += $(condition)$(p:G)$(project-id)//$(p:G=) ; + } + } + else + { + result += $(condition)$(p) ; + } + } + return $(result) ; +} + + # Class maintaining a property set -> string mapping. # class property-map diff --git a/v2/build/targets.jam b/v2/build/targets.jam index 0737552cf..20da57988 100644 --- a/v2/build/targets.jam +++ b/v2/build/targets.jam @@ -13,8 +13,8 @@ # each Jamfile, and can be obtained by the 'target' rule in the Jamfile's module # (see project.jam). # -# Project targets keep a list of 'main-target' instances. A main target is -# what the user explicitly defines in a Jamfile. It is possible to have several +# Project targets keep a list of 'main-target' instances. A main target is what +# the user explicitly defines in a Jamfile. It is possible to have several # definitions for a main target, for example to have different lists of sources # for different platforms. So, main targets keep a list of alternatives. # @@ -89,8 +89,8 @@ class abstract-target import "class" ; import errors ; - rule __init__ ( name # name of the target in Jamfile - : project-target # the project target to which this one belongs + rule __init__ ( name # Name of the target in Jamfile. + : project-target # The project target to which this one belongs. ) { # Note: it might seem that we don't need either name or project at all. @@ -115,7 +115,7 @@ class abstract-target return $(self.project) ; } - # Return the location where the target was declared + # Return the location where the target was declared. rule location ( ) { return $(self.location) ; @@ -232,10 +232,8 @@ class project-target : abstract-target self.build-dir = [ get build-dir ] ; if ! $(self.build-dir) { - self.build-dir = [ path.join - [ $(self.project).get location ] - bin - ] ; + self.build-dir = [ path.join [ $(self.project).get location ] + bin ] ; } } return $(self.build-dir) ; @@ -300,8 +298,8 @@ class project-target : abstract-target # rule mark-target-as-explicit ( target-name ) { - # Record the name of the target, not instance, since this - # rule is called before main target instaces are created. + # Record the name of the target, not instance, since this rule is called + # before main target instances are created. self.explicit-targets += $(target-name) ; } @@ -311,13 +309,13 @@ class project-target : abstract-target { if $(self.built-main-targets) { - errors.error "add-alternative called when main targets are already created." - : "in project" [ full-name ] ; + errors.error add-alternative called when main targets are already + created. : in project [ full-name ] ; } self.alternatives += $(target-instance) ; } - # Returns a 'main-target' class instance corresponding to the 'name'. + # Returns a 'main-target' class instance corresponding to 'name'. # rule main-target ( name ) { @@ -325,11 +323,10 @@ class project-target : abstract-target { build-main-targets ; } - return $(self.main-target.$(name)) ; } - # Tells if a main target with the specified name exists. + # Returns whether a main target with the specified name exists. # rule has-main-target ( name ) { @@ -344,13 +341,12 @@ class project-target : abstract-target } } - # Find and return the target with the specified id, treated relative to - # self. + # Worker function for the find rule not implementing any caching and simply + # returning nothing in case the target can not be found. # rule find-really ( id ) { local result ; - local project = $(self.project) ; local current-location = [ get location ] ; local split = [ MATCH (.*)//(.*) : $(id) ] ; @@ -360,8 +356,8 @@ class project-target : abstract-target local extra-error-message ; if $(project-part) { - # There's explicit project part in id. Looks up the project and - # passes the request to it. + # There is an explicitly specified project part in id. Looks up the + # project and passes the request to it. local pm = [ project.find $(project-part) : $(current-location) ] ; if $(pm) { @@ -370,37 +366,44 @@ class project-target : abstract-target } else { - extra-error-message = "error: could not find project '$(project-part)'" ; + # TODO: This extra error message will not get displayed most + # likely due to some buggy refactoring. Refactor the code so the + # message gets diplayed again. + extra-error-message = error: could not find project + '$(project-part)' ; } } else { # Interpret target-name as name of main target. Need to do this - # before checking for file. Consider this: + # before checking for file. Consider the following scenario with a + # toolset not modifying its executable's names, e.g. gcc on + # Unix-like platforms: # # exe test : test.cpp ; # install s : test : . ; # - # After first build we'll have target 'test' in Jamfile and file - # 'test' on the disk. We need target to override the file. + # After the first build we would have a target named 'test' in the + # Jamfile and a file named 'test' on the disk. We need the target to + # override the file. result = [ main-target $(id) ] ; - + + # Interpret id as an existing file reference. if ! $(result) { - result = [ new file-reference [ path.make $(id) ] : $(project) ] ; - + result = [ new file-reference [ path.make $(id) ] : + $(self.project) ] ; if ! [ $(result).exists ] { - # File actually does not exist. Reset 'target' so that an - # error is issued. result = ; } } - # Interpret id as project-id + # Interpret id as project-id. if ! $(result) { - local project-module = [ project.find $(id) : $(current-location) ] ; + local project-module = [ project.find $(id) : + $(current-location) ] ; if $(project-module) { result = [ project.target $(project-module) ] ; @@ -411,6 +414,11 @@ class project-target : abstract-target return $(result) ; } + # Find and return the target with the specified id, treated relative to + # self. Id may specify either a target or a file name with the target taking + # priority. May report an error or return nothing if the target is not found + # depending on the 'no-error' parameter. + # rule find ( id : no-error ? ) { local v = $(.id.$(id)) ; @@ -490,7 +498,7 @@ class project-target : abstract-target self.constants += $(name) ; } self.constant.$(name) = $(value) ; - # Inject the constant in the scope of project-root module. + # Inject the constant in the scope of the Jamroot module. modules.poke $(self.project-module) : $(name) : $(value) ; } @@ -771,7 +779,7 @@ class main-target : abstract-target } -# Abstract target which refers to a source file. This is an artificial entity +# Abstract target refering to a source file. This is an artificial entity # allowing sources to a target to be represented using a list of abstract target # instances. # @@ -788,11 +796,8 @@ class file-reference : abstract-target rule generate ( properties ) { - location ; - return [ property-set.empty ] - [ virtual-target.from-file $(self.name) - : $(self.file-location) - : $(self.project) ] ; + return [ property-set.empty ] [ virtual-target.from-file $(self.name) : + [ location ] : $(self.project) ] ; } # Returns true if the referred file really exists. @@ -909,7 +914,7 @@ rule common-properties ( build-request 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 evaluating the condition. For indirect conditional # requirements, this means calling a rule. Ordinary requirements are always # applied. # @@ -945,7 +950,7 @@ rule evaluate-requirements ( requirements : context : what ) local conditionals = [ $(requirements).conditional ] ; # The 'count' variable has one element for each conditional feature and for - # each occurence of '' feature. It is used as a loop + # each occurrence of '' 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 are done. It is assumed that # #conditionals iterations should be enough for properties to propagate @@ -959,9 +964,10 @@ rule evaluate-requirements ( requirements : context : what ) local current = $(raw) ; # It is assumed that ordinary conditional requirements can not add - # properties, and that rules referred to by - # properties can not add new - # properties. So the list of indirect conditionals does not change. + # properties (a.k.a. indirect conditional properties), and + # that rules referred to by properties can not add new + # properties. So the list of indirect conditionals does not + # change. local indirect = [ $(requirements).get ] ; indirect = [ MATCH @(.*) : $(indirect) ] ; @@ -980,7 +986,7 @@ rule evaluate-requirements ( requirements : context : what ) if $(e) = $(added-requirements) { - # If we got the same result, we've found final properties. + # If we got the same result, we have found the final properties. count = ; ok = true ; } @@ -1009,7 +1015,7 @@ rule evaluate-requirements ( requirements : context : what ) } else { - errors.error "Invalid value of the 'what' parameter" ; + errors.error "Invalid value of the 'what' parameter." ; } } @@ -1074,7 +1080,8 @@ class basic-target : abstract-target if $(sources:G) { - errors.user-error "properties found in the 'sources' parameter for" [ full-name ] ; + errors.user-error properties found in the 'sources' parameter for + [ full-name ] ; } } @@ -1198,7 +1205,8 @@ class basic-target : abstract-target ECHO [ targets.indent ] "Common properties: " [ $(rproperties).raw ] ; } - if $(rproperties[1]) != "@error" && [ $(rproperties).get ] != no + if ( $(rproperties[1]) != "@error" ) && ( [ $(rproperties).get + ] != no ) { local source-targets ; local properties = [ $(rproperties).non-dependency ] ; @@ -1401,11 +1409,11 @@ class typed-target : basic-target { import generators ; - rule __init__ ( name : project : type : sources * : requirements * - : default-build * : usage-requirements * ) + rule __init__ ( name : project : type : sources * : requirements * : + default-build * : usage-requirements * ) { - basic-target.__init__ $(name) : $(project) : $(sources) - : $(requirements) : $(default-build) : $(usage-requirements) ; + basic-target.__init__ $(name) : $(project) : $(sources) : + $(requirements) : $(default-build) : $(usage-requirements) ; self.type = $(type) ; } @@ -1508,10 +1516,10 @@ rule main-target-usage-requirements ( { local project-usage-requirements = [ $(project).get usage-requirements ] ; - # We don't use 'refine-from-user-input' because: - # - I'm not sure if removing of parent's usage requirements makes sense - # - refining of usage requirements is not needed, since usage requirements - # are always free. + # We do not use 'refine-from-user-input' because: + # - I am not sure if removing parent's usage requirements makes sense + # - refining usage requirements is not needed, since usage requirements are + # always free. local usage-requirements = [ property-set.create-from-user-input $(specification) : [ $(project).project-module ] [ $(project).get location ] ] ; diff --git a/v2/build/toolset.jam b/v2/build/toolset.jam index 5e6a1b47c..7ada583ee 100644 --- a/v2/build/toolset.jam +++ b/v2/build/toolset.jam @@ -21,8 +21,8 @@ import set ; .ignore-requirements = ; -# This is used only for testing, to make sure we don't get random extra elements -# in paths. +# This is used only for testing, to make sure we do not get random extra +# elements in paths. if --ignore-toolset-requirements in [ modules.peek : ARGV ] { .ignore-requirements = 1 ; @@ -56,7 +56,7 @@ local rule normalize-condition ( property-sets * ) # Specifies if the 'flags' rule should check that the invoking module is the -# same as the module we're setting the flag for. 'v' can be either 'checked' or +# same as the module we are setting the flag for. 'v' can be either 'checked' or # 'unchecked'. Subsequent call to 'pop-checking-for-flags-module' will restore # the setting that was in effect before calling this rule. # @@ -101,7 +101,7 @@ rule flags ( # ia64/ # # Where both features are optional. Without this syntax - # we'd be forced to define "default" values. + # we would be forced to define "default" values. values * : # The value to add to variable. If is specified, # then the value of 'feature' will be added. @@ -138,7 +138,7 @@ rule flags ( if $(condition) && ! $(condition:G=) && ! $(hack-hack) { # We have condition in the form '', that is, without value. - # That's a previous syntax: + # That is an older syntax: # flags gcc.link RPATH ; # for compatibility, convert it to # flags gcc.link RPATH : ; @@ -162,10 +162,10 @@ local rule add-flag ( rule-or-module : variable-name : condition * : values * ) { .$(rule-or-module).flags += $(.flag-no) ; - # Store all flags for a module + # Store all flags for a module. local module_ = [ MATCH "([^.]*).*" : $(rule-or-module) ] ; .module-flags.$(module_) += $(.flag-no) ; - # Store flag-no -> rule-or-module mapping + # Store flag-no -> rule-or-module mapping. .rule-or-module.$(.flag-no) = $(rule-or-module) ; .$(rule-or-module).variable.$(.flag-no) += $(variable-name) ; @@ -177,7 +177,7 @@ local rule add-flag ( rule-or-module : variable-name : condition * : values * ) # Returns the first element of 'property-sets' which is a subset of -# 'properties', or an empty list if no such element exists. +# 'properties' or an empty list if no such element exists. # rule find-property-subset ( property-sets * : properties * ) { @@ -225,6 +225,9 @@ rule find-property-subset ( property-sets * : properties * ) } +# Returns a value to be added to some flag for some target based on the flag's +# value definition and the given target's property set. +# rule handle-flag-value ( value * : properties * ) { local result ; @@ -245,8 +248,8 @@ rule handle-flag-value ( value * : properties * ) local values ; # Treat features with && in the value specially -- each # &&-separated element is considered a separate value. This is - # needed to handle searched libraries, which must be in a - # specific order. + # needed to handle searched libraries or include paths, which + # may need to be in a specific order. if ! [ MATCH (&&) : $(p:G=) ] { values = $(p:G=) ; @@ -383,11 +386,11 @@ rule inherit-generators ( toolset properties * : base : generators-to-ignore * ) if ! $(id) in $(generators-to-ignore) { # Some generator names have multiple periods in their name, so - # $(id:B=$(toolset)) doesn't generate the right new-id name. E.g. if - # id = gcc.compile.c++, $(id:B=darwin) = darwin.c++, which is not - # what we want. Manually parse the base and suffix (if there's a - # better way to do this, I'd love to see it). See also register in - # module generators. + # $(id:B=$(toolset)) does not generate the right new-id name. E.g. + # if id = gcc.compile.c++ then $(id:B=darwin) = darwin.c++, which is + # not what we want. Manually parse the base and suffix. If there is + # a better way to do this, I would love to see it. See also the + # register() rule in the generators module. local base = $(id) ; local suffix = "" ; while $(base:S) @@ -405,14 +408,14 @@ rule inherit-generators ( toolset properties * : base : generators-to-ignore * ) # Brings all flag definitions from the 'base' toolset into the 'toolset' # toolset. Flag definitions whose conditions make use of properties in -# 'prohibited-properties' are ignored. Don't confuse property and feature, for +# 'prohibited-properties' are ignored. Do not confuse property and feature, for # example on and off, so blocking one of them does # not block the other one. # # The flag conditions are not altered at all, so if a condition includes a name, -# or version of a base toolset, it won't ever match the inheriting toolset. When -# such flag settings must be inherited, define a rule in base toolset module and -# call it as needed. +# or version of a base toolset, it will not ever match the inheriting toolset. +# When such flag settings must be inherited, define a rule in base toolset +# module and call it as needed. # rule inherit-flags ( toolset : base : prohibited-properties * ) { @@ -447,7 +450,7 @@ rule inherit-flags ( toolset : base : prohibited-properties * ) rule inherit-rules ( toolset : base ) { - # It appears that "action" creates a local rule... + # It appears that "action" creates a local rule. local base-generators = [ generators.generators-for-toolset $(base) ] ; local rules ; for local g in $(base-generators) @@ -456,8 +459,7 @@ rule inherit-rules ( toolset : base ) rules += $(id) ; } IMPORT $(base) : $(rules) : $(toolset) : $(rules) ; - # Import the rules to the global scope - IMPORT $(toolset) : $(rules) : : $(toolset).$(rules) ; + IMPORT $(base) : $(rules) : : $(toolset).$(rules) ; } diff --git a/v2/build/type.jam b/v2/build/type.jam index 2abc94fa8..0fdef8c3f 100644 --- a/v2/build/type.jam +++ b/v2/build/type.jam @@ -14,7 +14,8 @@ import project ; import property ; import scanner ; -# The follwing import would create a circular dependency: + +# The following import would create a circular dependency: # project -> project-root -> builtin -> type -> targets -> project # import targets ; @@ -48,15 +49,15 @@ rule register ( type : suffixes * : base-type ? ) else { .types += $(type) ; - .bases.$(type) = $(base-type) ; + .base.$(type) = $(base-type) ; .derived.$(base-type) += $(type) ; if $(suffixes)-is-not-empty { # Specify mapping from suffixes to type. register-suffixes $(suffixes) : $(type) ; - # Generated targets of 'type' will use the first of 'suffixes'. This - # may be overriden. + # By default generated targets of 'type' will use the first of + #'suffixes'. This may be overriden. set-generated-target-suffix $(type) : : $(suffixes[1]) ; } @@ -68,14 +69,18 @@ rule register ( type : suffixes * : base-type ? ) feature.compose $(type) : $(base-type) ; # We used to declare the main target rule only when a 'main' parameter - # was specified. However, it's hard to decide that a type will *never* - # need a main target rule and so from time to time we needed to make yet - # another type 'main'. So now a main target rule is defined for each - # type. + # has been specified. However, it is hard to decide that a type will + # *never* need a main target rule and so from time to time we needed to + # make yet another type 'main'. So now a main target rule is defined for + # each type. main-rule-name = [ type-to-rule-name $(type) ] ; .main-target-type.$(main-rule-name) = $(type) ; - IMPORT $(__name__) : main-target-rule : : $(main-rule-name) ; + + # Adding a new derived type affects generator selection so we need to + # make the generator selection module update any of its cached + # information related to a new derived type being defined. + generators.update-cached-information-with-a-new-type $(type) ; } } @@ -114,8 +119,8 @@ rule register-suffixes ( suffixes + : type ) } else if $(.type.$(s)) != type { - errors.error Attempting to specify multiple types for suffix \"$(s)\" - : "Old type $(.type.$(s)), New type $(type)" ; + errors.error Attempting to specify multiple types for suffix + \"$(s)\" : "Old type $(.type.$(s)), New type $(type)" ; } } } @@ -136,7 +141,7 @@ rule registered ( type ) # rule validate ( type ) { - if ! $(type) in $(.types) + if ! [ registered $(type) ] { errors.error "Unknown target type $(type)" ; } @@ -147,10 +152,7 @@ rule validate ( type ) # rule set-scanner ( type : scanner ) { - if ! $(type) in $(.types) - { - error "Type" $(type) "is not declared" ; - } + validate $(type) ; .scanner.$(type) = $(scanner) ; } @@ -166,6 +168,15 @@ rule get-scanner ( type : property-set ) } +# Returns a base type for the given type or nothing in case the given type is +# not derived. +# +rule base ( type ) +{ + return $(.base.$(type)) ; +} + + # Returns the given type and all of its base types in order of their distance # from type. # @@ -174,13 +185,16 @@ rule all-bases ( type ) local result = $(type) ; while $(type) { - type = $(.bases.$(type)) ; + type = [ base $(type) ] ; result += $(type) ; } return $(result) ; } +# Returns the given type and all of its derived types in order of their distance +# from type. +# rule all-derived ( type ) { local result = $(type) ; @@ -192,7 +206,8 @@ rule all-derived ( type ) } -# Returns true if 'type' has 'base' as its direct or indirect base. +# Returns true if 'type' is equal to 'base' or has 'base' as its direct or +# indirect base. # rule is-derived ( type base ) { @@ -202,19 +217,15 @@ rule is-derived ( type base ) } } - # Returns true if 'type' is either derived from or is equal to 'base'. # +# TODO: It might be that is-derived and is-subtype were meant to be different +# rules - one returning true for type = base and one not, but as currently +# implemented they are actually the same. Clean this up. +# rule is-subtype ( type base ) { - if $(type) = $(base) - { - return true ; - } - else - { - return [ is-derived $(type) $(base) ] ; - } + return [ is-derived $(type) $(base) ] ; } @@ -329,7 +340,7 @@ local rule generated-target-ps-real ( ps : type : properties * ) { found = true ; } - type = $(.bases.$(type)) ; + type = $(.base.$(type)) ; } if $(result) = "" { @@ -345,8 +356,8 @@ local rule generated-target-ps ( ps : type : property-set ) local v = $($(key)) ; if ! $(v) { - v = [ generated-target-ps-real $(ps) : $(type) - : [ $(property-set).raw ] ] ; + v = [ generated-target-ps-real $(ps) : $(type) : [ $(property-set).raw ] + ] ; if ! $(v) { v = none ; @@ -361,9 +372,9 @@ local rule generated-target-ps ( ps : type : property-set ) } -# 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. +# Returns file type given its 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 ) { @@ -379,23 +390,32 @@ rule type ( filename ) # Rule used to construct all main targets. Note that this rule gets imported -# into the global namespace under different alias names and exactly what type of -# target it is supposed to construct is read from the name of the alias rule -# actually used to invoke it. +# into the global namespace under different alias names and the exact target +# type to construct is selected based on the alias used to actually invoke this +# rule. # -rule main-target-rule ( name : sources * : requirements * : default-build * - : usage-requirements * ) +rule main-target-rule ( name : sources * : requirements * : default-build * : + usage-requirements * ) { - # First discover the required target type, which is equal to the rule name - # used to invoke us. + # First discover the required target type based on the exact alias used to + # invoke this rule. local bt = [ BACKTRACE 1 ] ; local rulename = $(bt[4]) ; + local target-type = [ type-from-rule-name $(rulename) ] ; - local project = [ project.current ] ; - - # This is a circular module dependency so it must be imported here. + # This is a circular module dependency and so must be imported here. import targets ; - return [ targets.create-typed-target $(.main-target-type.$(rulename)) - : $(project) : $(name) : $(sources) : $(requirements) - : $(default-build) : $(usage-requirements) ] ; + + return [ targets.create-typed-target $(target-type) : [ project.current ] : + $(name) : $(sources) : $(requirements) : $(default-build) : + $(usage-requirements) ] ; +} + + +rule __test__ ( ) +{ + import assert ; + + # TODO: Add tests for all the is-derived, is-base & related type relation + # checking rules. } diff --git a/v2/build/virtual-target.jam b/v2/build/virtual-target.jam index 487bcc455..ac6f58247 100644 --- a/v2/build/virtual-target.jam +++ b/v2/build/virtual-target.jam @@ -6,7 +6,7 @@ # Implements virtual targets, which correspond to actual files created during a # build, but are not yet targets in Jam sense. They are needed, for example, -# when searching for possible transformation sequences, when it's not yet known +# when searching for possible transformation sequences, when it is not yet known # whether a particular target should be created at all. import "class" : new ; @@ -17,6 +17,7 @@ import set ; import type ; import utility ; + # +--------------------------+ # | virtual-target | # +==========================+ @@ -88,18 +89,24 @@ class virtual-target # Name of this target. # - rule name ( ) { return $(self.name) ; } + rule name ( ) + { + return $(self.name) ; + } # Project of this target. # - rule project ( ) { return $(self.project) ; } + rule project ( ) + { + return $(self.project) ; + } # Adds additional 'virtual-target' instances this one depends on. # rule depends ( d + ) { - self.dependencies = [ sequence.merge $(self.dependencies) - : [ sequence.insertion-sort $(d) ] ] ; + self.dependencies = [ sequence.merge $(self.dependencies) : + [ sequence.insertion-sort $(d) ] ] ; } rule dependencies ( ) @@ -185,7 +192,8 @@ class virtual-target { # In fact, we just need to merge virtual-target with # abstract-file-target as the latter is the only class derived from the - # former. But that's for later. + # former. But that has been left for later. + errors.error "method should be defined in derived classes" ; } } @@ -197,8 +205,9 @@ class virtual-target # May be a source file (when no action is specified) or a derived file # (otherwise). # -# The target's grist is concatenation of its project's location, properties of -# action (for derived files) and, optionally, value identifying the main target. +# The target's grist is a concatenation of its project's location, action +# properties (for derived targets) and, optionally, value identifying the main +# target. # class abstract-file-target : virtual-target { @@ -236,7 +245,10 @@ class abstract-file-target : virtual-target } } - rule type ( ) { return $(self.type) ; } + rule type ( ) + { + return $(self.type) ; + } # Sets the path. When generating target name, it will override any path # computation from properties. @@ -291,11 +303,11 @@ class abstract-file-target : virtual-target } # Return a human-readable representation of this target. If this target has - # an action, that's: + # an action, that is: # # { -. ... } # - # otherwise, it's: + # otherwise, it is: # # { . } # @@ -358,7 +370,7 @@ class abstract-file-target : virtual-target rule grist ( ) { # Depending on target, there may be different approaches to generating - # unique prefixes. We'll generate prefixes in the form + # unique prefixes. We generate prefixes in the form: # local path = [ path ] ; if $(path) @@ -441,7 +453,7 @@ class abstract-file-target : virtual-target } } - # If there's no tag or the tag rule returned nothing. + # If there is no tag or the tag rule returned nothing. if ! $(tag) || ! $(self.name) { self.name = [ virtual-target.add-prefix-and-suffix $(specified-name) @@ -460,7 +472,7 @@ class abstract-file-target : virtual-target if $(self.action) { - # For non-derived target, we don't care if there are several + # For non-derived target, we do not care if there are several # virtual targets that refer to the same name. One case when # this is unavoidable is when the file name is main.cpp and two # targets have types CPP (for compiling) and MOCCABLE_CPP (for @@ -531,23 +543,23 @@ class file-target : abstract-file-target import errors ; rule __init__ ( - name exact ? - : type ? # Optional type for this target + name exact ? + : type ? # Optional type for this target. : project : action ? : path ? ) { - abstract-file-target.__init__ $(name) $(exact) : $(type) : $(project) - : $(action) ; + abstract-file-target.__init__ $(name) $(exact) : $(type) : $(project) : + $(action) ; self.path = $(path) ; } rule clone-with-different-type ( new-type ) { - return [ new file-target $(self.name) exact : $(new-type) - : $(self.project) : $(self.action) : $(self.path) ] ; + return [ new file-target $(self.name) exact : $(new-type) : + $(self.project) : $(self.action) : $(self.path) ] ; } rule actualize-location ( target ) @@ -581,14 +593,14 @@ class file-target : abstract-file-target # target has no directory name and uses a special grist. # # First, that means that "bjam hello.o" will build all known hello.o - # targets. Second, the grist makes sure this target won't be + # targets. Second, the grist makes sure this target will not be # confused with other targets, for example, if we have subdir 'test' # with target 'test' in it that includes a 'test.o' file, then the # target for directory will be just 'test' the target for test.o # will be test.o and the target we create below # will be test.o DEPENDS $(target:G=e) : $(target) ; - # Allow bjam / to work. This won't catch all + # Allow bjam / to work. This will not catch all # possible ways to refer to the path (relative/absolute, extra ".", # various "..", but should help in obvious cases. DEPENDS $(target:G=e:R=$(path)) : $(target) ; @@ -608,13 +620,13 @@ class file-target : abstract-file-target if $(self.action) { local p = [ $(self.action).properties ] ; - local path = [ $(p).target-path ] ; + local path,relative-to-build-dir = [ $(p).target-path ] ; + local path = $(path,relative-to-build-dir[1]) ; + local relative-to-build-dir = $(path,relative-to-build-dir[2]) ; - if $(path[2]) = true + if $(relative-to-build-dir) { - # Indicates that the path is relative to the build dir. - path = [ path.join [ $(self.project).build-dir ] - $(path[1]) ] ; + path = [ path.join [ $(self.project).build-dir ] $(path) ] ; } self.path = [ path.native $(path) ] ; @@ -727,7 +739,8 @@ class action actualize-sources [ sources ] : $(properties) ; - DEPENDS $(actual-targets) : $(self.actual-sources) $(self.dependency-only-sources) ; + DEPENDS $(actual-targets) : $(self.actual-sources) + $(self.dependency-only-sources) ; # Action name can include additional argument to rule, which should # not be passed to 'set-target-variables' @@ -794,8 +807,8 @@ class action # # For bjam to find the dependency the generated target must be # actualized (i.e. have its Jam target constructed). In the above case, - # if we're building just hello ("bjam hello"), 'a.h' won't be actualized - # unless we do it here. + # if we are building just hello ("bjam hello"), 'a.h' will not be + # actualized unless we do it here. local implicit = [ $(self.properties).get ] ; for local i in $(implicit) { @@ -816,7 +829,7 @@ class action # Action class which does nothing --- it produces the targets with specific -# properties out of nowhere. It's needed to distinguish virtual targets with +# properties out of nowhere. It is needed to distinguish virtual targets with # different properties that are known to exist and have no actions which create # them. # @@ -866,16 +879,21 @@ class non-scanning-action : action # Creates a virtual target with an appropriate name and type from 'file'. If a # target with that name in that project already exists, returns that already # created target. +# # FIXME: a more correct way would be to compute the path to the file, based on # name and source location for the project, and use that path to determine if -# the target was already created. +# the target has already been created. This logic should be shared with how we +# usually find targets identified by a specific target id. It should also be +# updated to work correctly when the file is specified using both relative and +# absolute paths. +# # TODO: passing a project with all virtual targets is starting to be annoying. # rule from-file ( file : file-loc : project ) { import type ; # Had to do this here to break a circular dependency. - # Check if we've created a target corresponding to this file. + # Check whether we already created a target corresponding to this file. local path = [ path.root [ path.root $(file) $(file-loc) ] [ path.pwd ] ] ; if $(.files.$(path)) @@ -888,11 +906,8 @@ rule from-file ( file : file-loc : project ) local type = [ type.type $(file) ] ; local result ; - result = [ new file-target $(file) - : $(type) - : $(project) - : #action - : $(file-loc) ] ; + result = [ new file-target $(file) : $(type) : $(project) : : + $(file-loc) ] ; .files.$(path) = $(result) ; return $(result) ; @@ -900,7 +915,7 @@ rule from-file ( file : file-loc : project ) } -# Registers a new virtual target. Checks if there's already a registered target +# Registers a new virtual target. Checks if there is already a registered target # with the same name, type, project and subvariant properties as well as the # same sources and equal action. If such target is found it is returned and a # new 'target' is not registered. Otherwise, 'target' is registered and @@ -926,15 +941,15 @@ rule register ( target ) else { if $(a1) && $(a2) && - [ $(a1).action-name ] = [ $(a2).action-name ] && - [ $(a1).sources ] = [ $(a2).sources ] + ( [ $(a1).action-name ] = [ $(a2).action-name ] ) && + ( [ $(a1).sources ] = [ $(a2).sources ] ) { local ps1 = [ $(a1).properties ] ; local ps2 = [ $(a2).properties ] ; - local p1 = [ $(ps1).base ] [ $(ps1).free ] - [ set.difference [ $(ps1).dependency ] : [ $(ps1).incidental ] ] ; - local p2 = [ $(ps2).base ] [ $(ps2).free ] - [ set.difference [ $(ps2).dependency ] : [ $(ps2).incidental ] ] ; + local p1 = [ $(ps1).base ] [ $(ps1).free ] [ set.difference + [ $(ps1).dependency ] : [ $(ps1).incidental ] ] ; + local p2 = [ $(ps2).base ] [ $(ps2).free ] [ set.difference + [ $(ps2).dependency ] : [ $(ps2).incidental ] ] ; if $(p1) = $(p2) { result = $(t) ; @@ -957,10 +972,10 @@ rule register ( target ) } -# Each target returned by 'register' is added to a .recent-targets list, +# Each target returned by 'register' is added to the .recent-targets list, # returned by this function. This allows us to find all virtual targets created -# when building a given main target, even those constructed only as intermediate -# targets. +# when building a specific main target, even those constructed only as +# intermediate targets. # rule recent-targets ( ) { @@ -1040,9 +1055,9 @@ rule register-actual-name ( actual-name : virtual-target ) # Traverses the dependency graph of 'target' and return all targets that will be # created before this one is created. If the root of some dependency graph is -# found during traversal, it's either included or not, depending on the value of -# 'include-roots'. In either case traversal stops at root targets, i.e. sources -# of root targets are not traversed. +# found during traversal, it is either included or not, depending on the +# 'include-roots' value. In either case traversal stops at root targets, i.e. +# root target sources are not traversed. # rule traverse ( target : include-roots ? : include-sources ? ) { @@ -1097,9 +1112,9 @@ rule clone-action ( action : new-project : new-action-name ? : new-properties ? for local target in [ $(action).targets ] { local n = [ $(target).name ] ; - # Don't modify produced targets names. - local cloned-target = [ class.new file-target $(n) exact - : [ $(target).type ] : $(new-project) : $(cloned-action) ] ; + # Do not modify produced target names. + local cloned-target = [ class.new file-target $(n) exact : + [ $(target).type ] : $(new-project) : $(cloned-action) ] ; local d = [ $(target).dependencies ] ; if $(d) { diff --git a/v2/contrib/wxFormBuilder.jam b/v2/contrib/wxFormBuilder.jam new file mode 100644 index 000000000..c9ee2de72 --- /dev/null +++ b/v2/contrib/wxFormBuilder.jam @@ -0,0 +1,195 @@ +################################################################################ +# +# Copyright (c) 2007-2008 Dario Senic, Jurko Gospodnetic. +# +# Use, modification and distribution is subject to the Boost Software +# License Version 1.0. (See accompanying file LICENSE_1_0.txt or +# http://www.boost.org/LICENSE_1_0.txt) +# +################################################################################ + +################################################################################ +# +# Boost Build wxFormBuilder generator tool module. +# +# wxFormBuilder is a GUI designer tool for the wxWidgets library. It can then +# generate C++ sources modeling the designed GUI using the wxWidgets library +# APIs. +# +# This module defines a wxFormBuilder project file type and rules needed to +# generate C++ source files from those projects. With it you can simply list +# wxFormBuilder projects as sources for some target and Boost Build will +# automatically convert them to C++ sources and process from there. +# +# The wxFormBuilder executable location may be provided as a parameter when +# configuring this toolset. Otherwise the default wxFormBuilder.exe executable +# name is used located in the folder pointed to by the WXFORMBUILDER environment +# variable. +# +# Current limitations: +# +# * Works only on Windows. +# * Works only when run via Boost Jam using the native Windows cmd.exe command +# interpreter, i.e. the default native Windows Boost Jam build. +# * Used wxFormBuilder projects need to have their output file names defined +# consistently with target names assumed by this build script. This means +# that their target names must use the prefix 'wxFormBuilderGenerated_' and +# have no output folder defined where the base name is equal to the .fpb +# project file's name. +# +################################################################################ + +################################################################################ +# +# Implementation note: +# +# Avoiding the limitation on the generated target file names can be done but +# would require depending on external tools to copy the wxFormBuilder project to +# a temp location and then modify it in-place to set its target file names. On +# the other hand wxFormBuilder is expected to add command-line options for +# choosing the target file names from the command line which will allow us to +# remove this limitation in a much cleaner way. +# (23.08.2008.) (Jurko) +# +################################################################################ + +import generators ; +import os ; +import path ; +import toolset ; +import type ; + + +################################################################################ +# +# wxFormBuilder.generate() +# ------------------------ +# +# Action for processing WX_FORM_BUILDER_PROJECT types. +# +################################################################################ +# +# Implementation notes: +# +# wxFormBuilder generated CPP and H files need to be moved to the location +# where the Boost Build target system expects them so that the generated CPP +# file can be included into the compile process and that the clean rule +# succesfully deletes both CPP and H files. We expect wxFormBuilder to generate +# files in the same location where the provided WX_FORM_BUILDER_PROJECT file is +# located. +# (15.05.2007.) (Dario) +# +################################################################################ + +actions generate +{ + start "" /wait "$(EXECUTABLE)" /g "$(2)" + move "$(1[1]:BSR=$(2:P))" "$(1[1]:P)" + move "$(1[2]:BSR=$(2:P))" "$(1[2]:P)" +} + + +################################################################################ +# +# wxFormBuilder.init() +# -------------------- +# +# Main toolset initialization rule called via the toolset.using rule. +# +################################################################################ + +rule init ( executable ? ) +{ + if $(.initialized) + { + if $(.debug-configuration) + { + ECHO notice: [wxFormBuilder-cfg] Repeated initialization request + (executable \"$(executable:E="")\") detected and ignored. ; + } + } + else + { + local environmentVariable = WXFORMBUILDER ; + + if $(.debug-configuration) + { + ECHO notice: [wxFormBuilder-cfg] Configuring wxFormBuilder... ; + } + + # Deduce the path to the used wxFormBuilder executable. + if ! $(executable) + { + executable = "wxFormBuilder.exe" ; + local executable-path = [ os.environ $(environmentVariable) ] ; + if $(executable-path)-is-not-empty + { + executable = [ path.root $(executable) $(executable-path) ] ; + } + else if $(.debug-configuration) + { + ECHO notice: [wxFormBuilder-cfg] No wxFormBuilder path + configured either explicitly or using the + $(environmentVariable) environment variable. ; + ECHO notice: [wxFormBuilder-cfg] To avoid complications please + update your configuration to includes a correct path to the + wxFormBuilder executable. ; + ECHO notice: [wxFormBuilder-cfg] wxFormBuilder executable will + be searched for on the system path. ; + } + } + if $(.debug-configuration) + { + ECHO notice: [wxFormBuilder-cfg] Will use wxFormBuilder executable + \"$(executable)\". ; + } + + # Now we are sure we have everything we need to initialize this toolset. + .initialized = true ; + + # Store the path to the used wxFormBuilder executable. + .executable = $(executable) ; + + # Type registration. + type.register WX_FORM_BUILDER_PROJECT : fbp ; + + # Parameters to be forwarded to the action rule. + toolset.flags wxFormBuilder.generate EXECUTABLE : $(.executable) ; + + # Generator definition and registration. + generators.register-standard wxFormBuilder.generate : + WX_FORM_BUILDER_PROJECT : CPP(wxFormBuilderGenerated_%) + H(wxFormBuilderGenerated_%) ; + } +} + + +################################################################################ +# +# wxFormBuilder.is-initialized() +# ------------------------------ +# +# Returns whether this toolset has been initialized. +# +################################################################################ + +rule is-initialized ( ) +{ + return $(.initialized) ; +} + + +################################################################################ +# +# Startup code executed when loading this module. +# +################################################################################ + +# Global variables for this module. +.executable = ; +.initialized = ; + +if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] +{ + .debug-configuration = true ; +} diff --git a/v2/doc/Jamfile.v2 b/v2/doc/jamfile.jam similarity index 100% rename from v2/doc/Jamfile.v2 rename to v2/doc/jamfile.jam diff --git a/v2/doc/src/advanced.xml b/v2/doc/src/advanced.xml index 598848d1d..76800ae0b 100644 --- a/v2/doc/src/advanced.xml +++ b/v2/doc/src/advanced.xml @@ -5,60 +5,78 @@ Overview - This section will provide the information necessary to create your own - projects using Boost.Build. The information provided here is relatively - high-level, and as well as the on-line help - system must be used to obtain low-level documentation (see ). + + This section will provide the information necessary to create your own + projects using Boost.Build. The information provided here is relatively + high-level, and as well as the on-line + help system must be used to obtain low-level documentation (see ). + - 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 - bjam on the command line is: + + 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 + bjam on the command line is as follows: - Boost.Jam tries to find Boost.Build and loads the top-level - module. The exact process is described in - - - The top-level module loads user-defined configuration files, - user-config.jam and - site-config.jam, which define available toolsets. + + Boost.Jam tries to find Boost.Build and loads the top-level module. + The exact process is described in - The Jamfile in the current directory is read. That in turn - might cause reading of further Jamfiles. As a result, a tree of - projects is created, with targets inside projects. + + The top-level module loads user-defined configuration files, + user-config.jam and site-config.jam + , which define available toolsets. + - Finally, using the build request specified on the command line, - 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. + + The Jamfile in the current directory is read. That in turn might + cause reading of further Jamfiles. As a result, a tree of projects + is created, with targets inside projects. + + + + + Finally, using the build request specified on the command line, + Boost.Build decides which targets should be built and how. That + information is passed back to Boost.Jam, which takes care of + actually running the scheduled build action commands. + - So, to be able to successfully use Boost.Build, you need to know only - four things: + + So, to be able to successfully use Boost.Build, you need to know only four + things: - - How to configure Boost.Build + + How to configure + Boost.Build + - - How to write declares targets in Jamfiles + + How to declare targets in + Jamfiles + - - How the build process works + + How the build process + works + - Some Basics about the Boost.Jam language. See - . + + Some Basics about the Boost.Jam language. See . @@ -67,153 +85,187 @@
Boost.Jam Language - This section will describe the basics of the Boost.Jam - language—just enough for writing Jamfiles. For more information, - please see the Boost.Jam documentation. - - - Boost.Jam has an interpreted, - procedural language. On the lowest level, a - Boost.Jam program consists of variables and - rule - rules (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. - - Syntantically, a Boost.Jam program - consists of two kind of elements—keywords (which have a special - meaning to Boost.Jam) and literals. - - Consider this code: - -a = b ; - which assigns the value b to the variable - a. Here, = and ; - are keywords, while a and b are - literals. - - All syntax elements, even keywords, must be separated by spaces. - For example, omitting the space character before ; - will lead to a syntax error. - - - If you want to use a literal value that is the same as some keyword, the - value can be quoted: - -a = "=" ; - - - 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 using the - $(variable) syntax. For example: - -a = $(b) $(c) ; + + This section will describe the basics of the Boost.Jam language— + just enough for writing Jamfiles. For more information, please see the + Boost.Jam documentation. - Rules are defined by specifying the rule name, the parameter names, - and the allowed size of the list value for each parameter. - + Boost.Jam has an interpreted, procedural + language. On the lowest level, a Boost.Jam + program consists of variables and rule + rules (Jam term for + function). They are grouped into modules—there is one global + module and a number of named modules. Besides that, a Boost.Jam program contains classes and class + instances. + + + + Syntantically, a Boost.Jam program + consists of two kind of elements—keywords (which have a special + meaning to Boost.Jam) and literals. + Consider this code: + +a = b ; + + which assigns the value b to the variable a + . Here, = and ; are + keywords, while a and b are + literals. + + + All syntax elements, even keywords, must be separated by spaces. For + example, omitting the space character before ; + will lead to a syntax error. + + + If you want to use a literal value that is the same as some keyword, the + value can be quoted: + +a = "=" ; + + + + + 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 using the + $(variable) syntax. For example: + +a = $(b) $(c) ; + + + + + Rules are defined by specifying the rule name, the parameter names, and + the allowed value list size for each parameter. + rule example - ( - parameter1 : - parameter2 ? : - parameter3 + : - parameter4 * - ) - { - // body - } + ( + parameter1 : + parameter2 ? : + parameter3 + : + parameter4 * + ) + { + # rule body + } + 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 arbitrarily long, but the third argument may not be empty. - The overview of Boost.Jam language - statements is given below: - + + The overview of Boost.Jam language + statements is given below: + helper 1 : 2 : 3 ; -x = [ helper 1 : 2 : 3 ] ; - 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 - brackets around the call, like shown on the second line. - -if cond { statements } [ else { statements } ] - This is a regular if-statement. The condition is composed of: - - Literals (true if at least one string is not empty) - Comparisons: a - operator b where - operator is one of =, - !=, <, >, - <=, >=. The comparison is done - pairwise between each string in the left and the right arguments. - - - Logical operations: ! a, a && - b, a || b - Grouping: ( cond ) - - -for var in list { statements } - Executes statements for each element in list, setting the variable - var to the element value. - -while cond { statements } - Repeatedly execute statements while cond remains true upon entry. - +x = [ helper 1 : 2 : 3 ] ; + + 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 + brackets around the call, like shown on the second line. + +if cond { statements } [ else { statements } ] + + This is a regular if-statement. The condition is composed of: + + + + Literals (true if at least one string is not empty) + + + + + Comparisons: a operator b + where operator is one of + =, !=, <, + >, <= or >=. The + comparison is done pairwise between each string in the left and + the right arguments. + + + + + Logical operations: ! a, a && b, + a || b + + + + + Grouping: ( cond ) + + + + +for var in list { statements } + + Executes statements for each element in list, setting the variable + var to the element value. + +while cond { statements } + + Repeatedly execute statements while cond remains true upon entry. + return values ; - This statement should be used only inside a - rule and assigns values to the return value of the - rule. - - The return statement does not exit the rule. For example: - + + This statement should be used only inside a rule and assigns + values to the return value of the rule. + + + The return statement does not exit the rule. For + example: + rule test ( ) { - if 1 = 1 { + if 1 = 1 + { return "reasonable" ; } return "strange" ; -} will return strange, not -reasonable. - - - +} + + will return strange, not + reasonable. + + + import module ; -import module : rule ; - The first form imports the specified bjam module. All rules from - that module are made available using the qualified name: - module.rule. - The second form imports the specified rules only, and they can be called - using unqualified names. +import module : rule ; + + The first form imports the specified bjam module. All rules from that + module are made available using the qualified name: + module.rule. The second + form imports the specified rules only, and they can be called using + unqualified names. Sometimes, you'd need to specify the actual command lines to be used - when creating targets. In jam language, you use named actions to do this. - For example: + when creating targets. In jam language, you use named actions to do + this. For example: actions create-file-from-another { create-file-from-another $(<) $(>) } - This specifies a named action called - create-file-from-another. The text inside braces is - the command to invoke. The $(<) variable will be - expanded to a list of generated files, and the - $(>) variable will be expanded to a list of - source files. + This specifies a named action called + create-file-from-another. The text inside braces is the + command to invoke. The $(<) variable will be + expanded to a list of generated files, and the $(>) + variable will be expanded to a list of source files. - 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: + + To flexibly adjust the command line, you can define a rule with the same + name as the action and taking three parameters -- targets, sources and + properties. For example: rule create-file-from-another ( targets * : sources * : properties * ) { @@ -227,18 +279,18 @@ actions create-file-from-another create-file-from-another $(OPTIONS) $(<) $(>) } - In this example, the rule checks if certain build property is specified. - If so, it sets variable OPIONS 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 OPTIONS in two unrelated actions - would be impossible. + In this example, the rule checks if certain build property is specified. + If so, it sets variable OPIONS 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 OPTIONS in + two unrelated actions would be impossible. - More details can be found in Jam reference, - + + More details can be found in Jam reference, . -
@@ -265,7 +317,7 @@ using tool-name ; default settings. For example, it will use the gcc executable found in the PATH, 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 + In case you have several versions of a compiler, it is installed in some unusual location, or you need to tweak its configuration, you'll need to pass additional parameters to the using rule. The parameters to using can be different for @@ -310,39 +362,39 @@ bjam --help tool-name.init using msvc : 7.1 ; using gcc ; -If the compiler can be found in the PATH but only by a -nonstandard name, you can just supply that name: + If the compiler can be found in the PATH but only by a + nonstandard name, you can just supply that name: using gcc : : g++-3.2 ; -Otherwise, it might be necessary to supply the complete path to the -compiler executable: + Otherwise, it might be necessary to supply the complete path to the + compiler executable: using msvc : : "Z:/Programs/Microsoft Visual Studio/vc98/bin/cl" ; -Some Boost.Build toolsets will use that path to take additional -actions required before invoking the compiler, such as calling -vendor-supplied scripts to set up its required environment variables. -When compiler executables for C and C++ are different, path to the C++ -compiler executable must be specified. The “invocation command” -can be any command allowed by the operating system. For example: + Some Boost.Build toolsets will use that path to take additional actions + required before invoking the compiler, such as calling vendor-supplied + scripts to set up its required environment variables. When compiler + executables for C and C++ are different, path to the C++ compiler + executable must be specified. The “invocation command” can + be any command allowed by the operating system. For example: using msvc : : echo Compiling && foo/bar/baz/cl ; -will work. + will work. - To configure several versions of a toolset, simply invoke - the using rule multiple times: + + To configure several versions of a toolset, simply invoke the + using rule multiple times: using gcc : 3.3 ; using gcc : 3.4 : g++-3.4 ; using gcc : 3.2 : g++-3.2 ; - Note that in the first call to - using, the compiler found in the - PATH will be used, and there's no need to - explicitly specify the command. + Note that in the first call to using, the + compiler found in the PATH will be used, and there is no + need to explicitly specify the command. As shown above, both the - The list of sources can also refer to other main targets. - Targets in the same project can be referred to by name, while - targets in other projects must be qualified with a directory or a - symbolic project name. The directory/project name is separated from - the target name by a double forward slash. There's no special syntax to - distinguish the directory name from the project name—the part before - the double slash is first looked up as project name, and then as directory - name. For example: + The list of sources can also refer to other main targets. Targets in + the same project can be referred to by name, while targets in other + projects must be qualified with a directory or a symbolic project + name. The directory/project name is separated from the target name by + a double forward slash. There is no special syntax to distinguish the + directory name from the project name—the part before the double + slash is first looked up as project name, and then as directory name. + For example: - lib helper : helper.cpp ; exe a : a.cpp helper ; -# Since all project ids start with slash, ".." is directory name. +# Since all project ids start with slash, ".." is a directory name. exe b : b.cpp ..//utils ; exe c : c.cpp /boost/program_options//program_options ; - The first exe uses the library defined in the same - project. The second one uses some target (most likely library) - defined by Jamfile one level higher. Finally, the third target - uses some C++ Boost - library, referring to it by absolute symbolic name. More - information about target references can be found in and C++ Boost library, referring to it using + its absolute symbolic name. More information about target references + can be found in and . -
diff --git a/v2/doc/src/faq.xml b/v2/doc/src/faq.xml index 4172479c1..fe1bd5a81 100644 --- a/v2/doc/src/faq.xml +++ b/v2/doc/src/faq.xml @@ -2,191 +2,232 @@ - - Frequently Asked Questions + + Frequently Asked Questions -
- - How do I get the current value of feature in Jamfile? - +
+ + How do I get the current value of feature in Jamfile? + - - This is not possible, since Jamfile does not have "current" value of any - feature, be it toolset, build variant or anything else. For a single invocation of - bjam, any given main target can be built with several property sets. - For example, user can request two build variants on the command line. Or one library - is built as shared when used from one application, and as static when used from another. - Obviously, Jamfile is read only once, so generally, there's no single value of a feature - you can access in Jamfile. - + + This is not possible, since Jamfile does not have "current" value of any + feature, be it toolset, build variant or anything else. For a single + invocation of bjam, any given main target can be + built with several property sets. For example, user can request two build + variants on the command line. Or one library is built as shared when used + from one application, and as static when used from another. Each Jamfile + is read only once so generally there is no single value of a feature you + can access in Jamfile. + - A feature has a specific value only when building a target, and there are two ways how you - can use that value: - - Use conditional requirements or indirect conditional requirements. See - . - - Define a custom generator and a custom main target type. The custom generator can do arbitrary processing - or properties. See the extender manual. - - + + A feature has a specific value only when building a target, and there are + two ways you can use that value: + -
+ + + + Use conditional requirements or indirect conditional requirements. See + . + + + + Define a custom generator and a custom main target type. The custom + generator can do arbitrary processing or properties. See the extender manual. + + +
-
- - I'm getting "Duplicate name of actual target" error. What - does it mean? - - - - The most likely case is that you're trying to - compile the same file twice, with almost the same, - but differing properties. For example: +
+ + I am getting a "Duplicate name of actual target" error. What does that + mean? + + + The most likely case is that you are trying to compile the same file + twice, with almost the same, but differing properties. For example: exe a : a.cpp : <include>/usr/local/include ; exe b : a.cpp ; - - + - The above snippet requires two different compilations - of 'a.cpp', which differ only in 'include' property. - Since the 'include' property is free, Boost.Build - can't generate two objects files into different directories. - On the other hand, it's dangerous to compile the file only - once -- maybe you really want to compile with different - includes. + The above snippet requires two different compilations of + a.cpp, which differ only in their include + property. Since the include feature is declared as + free Boost.Build does not create a separate build + directory for each of its values and those two builds would both produce + object files generated in the same build directory. Ignoring this and + compiling the file only once would be dangerous as different includes + could potentially cause completely different code to be compiled. - To solve this issue, you need to decide if file should - be compiled once or twice. + To solve this issue, you need to decide if the file should be compiled + once or twice. + - - Two compile file only once, make sure that properties - are the same: - + + + To compile the file only once, make sure that properties are the same + for both target requests: exe a : a.cpp : <include>/usr/local/include ; exe b : a.cpp : <include>/usr/local/include ; - - - - If changing the properties is not desirable, for example - if 'a' and 'b' target have other sources which need - specific properties, separate 'a.cpp' into it's own target: - + + or: -obj a_obj : a.cpp : <include>/usr/local/include ; -exe a : a_obj ; - - - - To compile file twice, you can make the object file local - to the main target: - +alias a-with-include : a.cpp : <include>/usr/local/include ; +exe a : a-with-include ; +exe b : a-with-include ; + + or if you want the includes property not to affect + how any other sources added for the built a and + b executables would be compiled: - exe a : [ obj a_obj : a.cpp ] : <include>/usr/local/include ; +obj a-obj : a.cpp : <include>/usr/local/include ; +exe a : a-obj ; +exe b : a-obj ; + + + + Note that in both of these cases the include + property will be applied only for building these object files and not + any other sources that might be added for targets a and + b. + + + + + + To compile the file twice, you can tell Boost.Build to compile it to + two separate object files like so: + + obj a_obj : a.cpp : <include>/usr/local/include ; + obj b_obj : a.cpp ; + exe a : a_obj ; + exe b : b_obj ; + + or you can make the object file targets local to the main target: + + exe a : [ obj a_obj : a.cpp : <include>/usr/local/include ] ; exe b : [ obj a_obj : a.cpp ] ; - + + which will cause Boost.Build to actually change the generated object + file names a bit for you and thus avoid any conflicts. + + + Note that in both of these cases the include + property will be applied only for building these object files and not + any other sources that might be added for targets a and + b. + + + - + + A good question is why Boost.Build can not use some of the above + approaches automatically. The problem is that such magic would only help + in half of the cases, while in the other half it would be silently doing + the wrong thing. It is simpler and safer to ask the user to clarify his + intention in such cases. + +
- - A good question is why Boost.Build can't use some of the above - approaches automatically. The problem is that such magic would - require additional implementation complexities and would only - help in half of the cases, while in other half we'd be silently - doing the wrong thing. It's simpler and safe to ask user to - clarify his intention in such cases. - - -
- -
- + <section id="bbv2.faq.envar"> + <title> Accessing environment variables - + - + Many users would like to use environment variables in Jamfiles, for - example, to control location of external libraries. In many cases you - better declare those external libraries in the site-config.jam file, as - documented in the recipes - section. However, if the users already have the environment variables set - up, it's not convenient to ask them to set up site-config.jam files as - well, and using environment variables might be reasonable. + example, to control the location of external libraries. In many cases it + is better to declare those external libraries in the site-config.jam file, + as documented in the recipes + section. However, if the users already have the environment + variables set up, it may not be convenient for them to set up their + site-config.jam files as well and using the environment variables might be + reasonable. - In Boost.Build V2, each Jamfile is a separate namespace, and the - variables defined in environment is imported into the global - namespace. Therefore, to access environment variable from Jamfile, you'd - need the following code: + + Boost.Jam automatically imports all environment variables into its + built-in .ENVIRON module so user can read them from there directly or by + using the helper os.environ rule. For example: + +import os ; +local unga-unga = [ os.environ UNGA_UNGA ] ; +ECHO $(unga-unga) ; + + or a bit more realistic: import os ; local SOME_LIBRARY_PATH = [ os.environ SOME_LIBRARY_PATH ] ; exe a : a.cpp : <include>$(SOME_LIBRARY_PATH) ; -
- -
- - How to control properties order? - - - For internal reasons, Boost.Build sorts all the properties - alphabetically. This means that if you write: - -exe a : a.cpp : <include>b <include>a ; - - then the command line with first mention the "a" include directory, and - then "b", even though they are specified in the opposite order. In most - cases, the user doesn't care. But sometimes the order of includes, or - other properties, is important. For example, if one uses both the C++ - Boost library and the "boost-sandbox" (libraries in development), then - include path for boost-sandbox must come first, because some headers may - override ones in C++ Boost. For such cases, a special syntax is - provided: - -exe a : a.cpp : <include>a&&b ; - - - - The && symbols separate values of an - property, and specify that the order of the values should be preserved. You - are advised to use this feature only when the order of properties really - matters, and not as a convenient shortcut. Using it everywhere might - negatively affect performance. - -
- How to control the library order on Unix? + How to control properties order? - On the Unix-like operating systems, the order in which static - libraries are specified when invoking the linker is important, because by - default, the linker uses one pass though the libraries list. Passing the - libraries in the incorrect order will lead to a link error. Further, this - behaviour is often used to make one library override symbols from - another. So, sometimes it's necessary to force specific order of - libraries. + + For internal reasons, Boost.Build sorts all the properties alphabetically. + This means that if you write: + +exe a : a.cpp : <include>b <include>a ; + + then the command line with first mention the a include + directory, and then b, even though they are specified in the + opposite order. In most cases, the user does not care. But sometimes the + order of includes, or other properties, is important. For such cases, a + special syntax is provided: + +exe a : a.cpp : <include>a&&b ; + - Boost.Build tries to automatically compute the right order. The - primary rule is that if library a "uses" library b, then library a will - appear on the command line before library b. Library a is considered to - use b is b is present either in the sources of a or in its - requirements. To explicitly specify the use relationship one can use the - <use> feature. For example, both of the following lines will cause - a to appear before b on the command line: + + The && symbols separate property values and specify + that their order should be preserved. You are advised to use this feature + only when the order of properties really matters and not as a convenient + shortcut. Using it everywhere might negatively affect performance. + +
+ +
+ + How to control the library linking order on Unix? + + + + On Unix-like operating systems, the order in which static libraries are + specified when invoking the linker is important, because by default, the + linker uses one pass though the libraries list. Passing the libraries in + the incorrect order will lead to a link error. Further, this behaviour is + often used to make one library override symbols from another. So, + sometimes it is necessary to force specific library linking order. + + + + Boost.Build tries to automatically compute the right order. The primary + rule is that if library a "uses" library b, then + library a will appear on the command line before library + b. Library a is considered to use b + if b is present either in the a library's + sources or its usage is listed in its requirements. To explicitly specify + the use relationship one can use the + <use> feature. For example, both of the following + lines will cause a to appear before b on the + command line: lib a : a.cpp b ; lib a : a.cpp : <use>b ; @@ -194,21 +235,22 @@ lib a : a.cpp : <use>b ; - The same approach works for searched libraries, too: + The same approach works for searched libraries as well: lib z ; lib png : : <use>z ; exe viewer : viewer png z ; -
- Can I get output of external program as a variable in a Jamfile? + <title> + Can I get capture external program output using a Boost.Jam variable? - The SHELL builtin can be used for the purpose: + + The SHELL builtin rule may be used for this purpose: local gtk_includes = [ SHELL "gtk-config --cflags" ] ; @@ -216,7 +258,8 @@ local gtk_includes = [ SHELL "gtk-config --cflags" ] ;
- How to get the project root (a.k.a. Jamroot.jam) location? + <title> + How to get the project root (a.k.a. Jamroot) location? @@ -230,18 +273,20 @@ path-constant TOP : . ;
- How to change compilation flags for one file? + <title> + How to change compilation flags for one file? - If one file must be compiled with special options, you need to - explicitly declare an obj target for that file and then use - that target in your exe or lib target: + + If one file must be compiled with special options, you need to explicitly + declare an obj target for that file and then use that target + in your exe or lib target: exe a : a.cpp b ; obj b : b.cpp : <optimization>off ; Of course you can use other properties, for example to specify specific - compiler options: + C/C++ compiler options: exe a : a.cpp b ; obj b : b.cpp : <cflags>-g ; @@ -252,149 +297,162 @@ obj b : b.cpp : <cflags>-g ; exe a : a.cpp b ; obj b : b.cpp : <variant>release:<optimization>off ; -
- Why are the <code>dll-path</code> and - <code>hardcode-dll-paths</code> properties useful? + <title> + Why are the <literal>dll-path</literal> and <literal>hardcode-dll-paths + </literal> properties useful? - - (This entry is specific to Unix system.)Before answering the - questions, let's recall a few points about shared libraries. Shared - libraries can be used by several applications, or other libraries, - without physically including the library in the application. This can - greatly decrease the total size of applications. It's also possible to - upgrade a shared library when the application is already - installed. Finally, shared linking can be faster. - - - However, the shared library must be found when the application is - started. The dynamic linker will search in a system-defined list of - paths, load the library and resolve the symbols. Which means that you - should either change the system-defined list, given by the - LD_LIBRARY_PATH environment variable, or install the - libraries to a system location. This can be inconvenient when - developing, since the libraries are not yet ready to be installed, and - cluttering system paths is undesirable. Luckily, on Unix there's another - way. - - - An executable can include a list of additional library paths, which - will be searched before system paths. This is excellent for development, - because the build system knows the paths to all libraries and can include - them in executables. That's done when the hardcode-dll-paths - feature has the true value, which is the - default. When the executables should be installed, the story is - different. + + + This entry is specific to Unix systems. + + + + Before answering the questions, let us recall a few points about shared + libraries. Shared libraries can be used by several applications, or other + libraries, without physically including the library in the application + which can greatly decrease the total application size. It is also possible + to upgrade a shared library when the application is already installed. - Obviously, installed executable should not hardcode paths to your - development tree. (The stage rule explicitly disables the - hardcode-dll-paths feature for that reason.) However, you - can use the dll-path feature to add explicit paths + However, in order for application depending on shared libraries to be + started the OS may need to find the shared library when the application is + started. The dynamic linker will search in a system-defined list of paths, + load the library and resolve the symbols. Which means that you should + either change the system-defined list, given by the LD_LIBRARY_PATH + environment variable, or install the libraries to a system + location. This can be inconvenient when developing, since the libraries + are not yet ready to be installed, and cluttering system paths may be + undesirable. Luckily, on Unix there is another way. + + + + An executable can include a list of additional library paths, which will + be searched before system paths. This is excellent for development because + the build system knows the paths to all libraries and can include them in + the executables. That is done when the hardcode-dll-paths + feature has the true value, which is the + default. When the executables should be installed, the story is different. + + + + Obviously, installed executable should not contain hardcoded paths to your + development tree. (The install rule explicitly disables the + hardcode-dll-paths feature for that reason.) However, + you can use the dll-path feature to add explicit paths manually. For example: -stage installed : application : <dll-path>/usr/lib/snake - <location>/usr/bin ; +install installed : application : <dll-path>/usr/lib/snake + <location>/usr/bin ; - will allow the application to find libraries placed to - /usr/lib/snake. + will allow the application to find libraries placed in the + /usr/lib/snake directory. - If you install libraries to a nonstandard location and add an - explicit path, you get more control over libraries which will be used. A - library of the same name in a system location will not be inadvertently - used. If you install libraries to a system location and do not add any - paths, the system administrator will have more control. Each library can - be individually upgraded, and all applications will use the new library. + + If you install libraries to a nonstandard location and add an explicit + path, you get more control over libraries which will be used. A library of + the same name in a system location will not be inadvertently used. If you + install libraries to a system location and do not add any paths, the + system administrator will have more control. Each library can be + individually upgraded, and all applications will use the new library. - Which approach is best depends on your situation. If the libraries - are relatively standalone and can be used by third party applications, - they should be installed in the system location. If you have lots of - libraries which can be used only by your application, it makes sense to - install it to a nonstandard directory and add an explicit path, like the - example above shows. Please also note that guidelines for different - systems differ in this respect. The Debian guidelines prohibit any - additional search paths, and Solaris guidelines suggest that they should + + Which approach is best depends on your situation. If the libraries are + relatively standalone and can be used by third party applications, they + should be installed in the system location. If you have lots of libraries + which can be used only by your application, it makes sense to install them + to a nonstandard directory and add an explicit path, like the example + above shows. Please also note that guidelines for different systems differ + in this respect. For example, the Debian GNU guidelines prohibit any + additional search paths while Solaris guidelines suggest that they should always be used. -
Targets in site-config.jam - It is desirable to declare standard libraries available on a - given system. Putting target declaration in Jamfile is not really - good, since locations of the libraries can vary. The solution is - to declare the targets in site-config.jam: + + It is desirable to declare standard libraries available on a given system. + Putting target declaration in a specific project's Jamfile is not really + good, since locations of the libraries can vary between different + development machines and then such declarations would need to be + duplicated in different projects. The solution is to declare the targets + in Boost.Build's site-config.jam configuration file: project site-config ; lib zlib : : <name>z ; + - Recall that both site-config.jam and - user-config.jam are projects, and everything - you can do in a Jamfile you can do in those files. So, you declare - a project id and a target. Now, one can write: + + Recall that both site-config.jam and + user-config.jam are projects, and everything you can + do in a Jamfile you can do in those files as well. So, you declare a + project id and a target. Now, one can write: exe hello : hello.cpp /site-config//zlib ; - in any Jamfile. - + in any Jamfile. +
Header-only libraries - In modern C++, libraries often consist of just header files, without - any source files to compile. To use such libraries, you need to add proper - includes and, maybe, defines, to your project. But with large number of - external libraries it becomes problematic to remember which libraries are - header only, and which are "real" ones. However, with Boost.Build a - header-only library can be declared as Boost.Build target and all - dependents can use such library without remebering if it's header-only or not. - - - Header-only libraries are declared using the alias rule, - that specifies only usage requirements, for example: - -alias mylib - : # no sources - : # no build requirements - : # no default build - : <include>whatever - ; - - The includes specified in usage requirements of mylib are - automatically added to build properties of all dependents. The dependents - need not care if mylib is header-only or not, and it's possible - to later make mylib into a regular compiled library. + + In modern C++, libraries often consist of just header files, without any + source files to compile. To use such libraries, you need to add proper + includes and possibly defines to your project. But with a large number of + external libraries it becomes problematic to remember which libraries are + header only, and which ones you have to link to. However, with Boost.Build + a header-only library can be declared as Boost.Build target and all + dependents can use such library without having to remeber whether it is a + header-only library or not. - If you already have proper usage requirements declared for project where - header-only library is defined, you don't need to duplicate them for + Header-only libraries may be declared using the alias rule, + specifying their include path as a part of its usage requirements, for + example: + +alias my-lib + : # no sources + : # no build requirements + : # no default build + : <include>whatever ; + + The includes specified in usage requirements of my-lib are + automatically added to all of its dependants' build properties. The + dependants need not care if my-lib is a header-only or not, + and it is possible to later make my-lib into a regular + compiled library without having to that its dependants' declarations. + + + + If you already have proper usage requirements declared for a project where + a header-only library is defined, you do not need to duplicate them for the alias target: project my : usage-requirements <include>whatever ; alias mylib ; - + -
+
- -
\ No newline at end of file +--> diff --git a/v2/doc/src/reference.xml b/v2/doc/src/reference.xml index 7f16230e0..449f6925c 100644 --- a/v2/doc/src/reference.xml +++ b/v2/doc/src/reference.xml @@ -420,41 +420,55 @@ path-constant DATA : data/a.txt ; - A feature that combines several low-level features, making - it easy to request common build configurations. + A feature combining several low-level features, making it easy to + request common build configurations. - Allowed values: debug, release, - profile. + + Allowed values: + debug, release, + profile. + - The value debug expands to + + The value debug expands to + <optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on - The value release expands to + + The value release expands to + <optimization>speed <debug-symbols>off <inlining>full <runtime-debugging>off - The value profile expands to the same as - release, plus: + + The value profile expands to the same as + release, plus: + <profiling>on <debug-symbols>on - User can define his own build variants using the variant rule from the common - module. - - Notee: Runtime - debugging is on in debug builds to suit the expectations of - people used to various IDEs. - + + Users can define their own build variants using the + variant rule from the common module. - + + + Note: Runtime debugging is on in + debug builds to suit the expectations of people used to various + IDEs. + + + + link @@ -465,10 +479,11 @@ path-constant DATA : data/a.txt ; static - A feature that controls how libraries are built. + A feature controling how libraries are built. - + + runtime linking @@ -720,7 +735,10 @@ path-constant DATA : data/a.txt ; instruction-set instruction-set - Allowed values for this feature depend on used toolset. + + Allowed values: depend on the used + toolset. + The instruction-set specifies for which specific instruction set the code should be generated. The @@ -751,6 +769,31 @@ path-constant DATA : data/a.txt ; + c++-template-depth + + + Allowed values: Any positive + integer. + + + + This feature allows configuring a C++ compiler with the maximal + template instantiation depth parameter. Specific toolsets may or may + not provide support for this feature depending on whether their + compilers provide a corresponding command-line option. + + + + Note: Due to some internal details + in the current Boost Build implementation it is not possible to have + features whose valid values are all positive integer. As a + workaround a large set of allowed values has been defined for this + feature and, if a different one is needed, user can easily add it by + calling the feature.extend rule. + + + +
@@ -970,9 +1013,9 @@ using msvc : &toolset_ops; ; - setup-amd64> - setup-i386> - setup-ia64> + setup-amd64 + setup-i386 + setup-ia64 The filename of the target platform specific environment setup script to run before invoking any of the tools diff --git a/v2/doc/src/tasks.xml b/v2/doc/src/tasks.xml index c6889b49e..6ae6f4c58 100644 --- a/v2/doc/src/tasks.xml +++ b/v2/doc/src/tasks.xml @@ -9,328 +9,339 @@ Common tasks - This section describes main targets types that Boost.Build supports - out-of-the-box. Unless otherwise noted, all mentioned main target rules have - the common signature, described in . + + This section describes main targets types that Boost.Build supports + out-of-the-box. Unless otherwise noted, all mentioned main target rules have + the common signature, described in .
Programs - exe - Programs are created using the exe rule, which follows - the common syntax. - For example: + exe + + Programs are created using the exe rule, which follows the + common syntax. For + example: exe hello : hello.cpp some_library.lib /some_project//library : <threading>multi ; - This will create an executable file from the sources -- in this case, - one C++ file, one library file present in the same directory, and - another library that is created by Boost.Build. Generally, sources - can include C and C++ files, object files and libraries. Boost.Build - will automatically try to convert targets of other types. + This will create an executable file from the sources -- in this case, one + C++ file, one library file present in the same directory, and another + library that is created by Boost.Build. Generally, sources can include C + and C++ files, object files and libraries. Boost.Build will automatically + try to convert targets of other types. + + + + + On Windows, if an application uses shared libraries, and both the + application and the libraries are built using Boost.Build, it is not + possible to immediately run the application, because the PATH + environment variable should include the path to the + libraries. It means you have to either add the paths manually, or have + the build place the application and the libraries into the same + directory. See . + + +
- - - 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 - PATH environment variable should include the path - to the libraries. It means you have to either add the paths - manually, or place the application and the libraries to the same - directory. See . - - - - +
+ Libraries -
- Libraries - - Libraries are created using the lib rule, which - follows the common - syntax. For example: + + Library targets are created using the lib rule, which + follows the common syntax + . For example: -lib helpers : helpers.cpp : <include>boost : : <include>. ; +lib helpers : helpers.cpp ; - - - - In the most common case, the lib 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). The second case is where the library is - available as a prebuilt file and the full path is known. - - + This will define a library target named helpers built from + the helpers.cpp source file. + + + Depending on the given <link> feature value the library will be + either static or shared. + + + Library targets may be used to represent: + + + + Built libraries that get built from specified sources, + as is the one in the example above. + + + + + Prebuilt libraries which already exist on the system + and are just supposed to be used by the build system. Such + libraries may be searched for by the tools using them (typically + linkers referencing the library using the + option) or their path may be known in advance by the build system. + + + + + - - The syntax for these case is given below: + + The syntax for these case is given below: lib z : : <name>z <search>/home/ghost ; lib compress : : <file>/opt/libs/compress.a ; - The name property specifies the name that should be - passed to the option, and the file - property specifies the file location. The search feature - specifies paths in which to search for the library. That feature can - be specified several times, or it can be omitted, in which case only - default compiler paths will be searched. - + The name property specifies the name that should be passed to + the option, and the file property + specifies the file location. The search feature + specifies paths in which to search for the library. That feature can be + specified several times or it can be omitted, in which case only the + default compiler paths will be searched. + - The difference between using the file feature as - opposed to the name feature together with the - search feature is that file is more - precise. A specific file will be used. On the other hand, the - search feature only adds a library path, and the - name feature gives the basic name of the library. The - search rules are specific to the linker. For example, given these - definition: + + The difference between using the file feature as + opposed to the name feature together with the + search feature is that file is more precise. + A specific file will be used as opposed to the search + feature only adding a library path, or the name feature + giving only the basic name of the library. The search rules are specific + to the linker used. For example, given these definition: lib a : : <variant>release <file>/pool/release/a.so ; lib a : : <variant>debug <file>/pool/debug/a.so ; lib b : : <variant>release <file>/pool/release/b.so ; lib b : : <variant>debug <file>/pool/debug/b.so ; - It's possible to use release version of a and debug - version of b. Had we used the name and - search features, the linker would always pick either - release or debug versions. - - + It is possible to use a release version of a and debug + version of b. Had we used the name and + search features, the linker would have always picked + either the release or the debug versions. + + - - For convenience, the following syntax is allowed: + + For convenience, the following syntax is allowed: lib z ; lib gui db aux ; - and is does exactly the same as: + which has exactly the same effect as: lib z : : <name>z ; lib gui : : <name>gui ; lib db : : <name>db ; lib aux : : <name>aux ; - + - - 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: + + When a library references another library you should put that other + library in its 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: lib z ; lib png : z : <name>png ; - - - - - When a library (say, a), that has another library, (say, - b) - - is linked dynamically, the b - library will be incorporated - - in a. (If b - is dynamic library as well, then a will only refer to it, - and not include any extra code.) - - When the a - library is linked statically, Boost.Build will assure that all - executables that link to a will also link to - b. - - + + - One feature of Boost.Build that is very important for libraries is usage - requirements. - - For example, if you write: - -lib helpers : helpers.cpp : : : <include>. ; - - then the compiler include path for all targets that use - helpers will contain the directory - - where the target is defined.path to "helpers.cpp". The user - only needs to add helpers to the list of sources, - and needn't consider the requirements its use imposes on a - dependent target. This feature greatly simplifies Jamfiles. - + When a library has a shared library defined as its source, or a static + library has another static library defined as its source then any target + linking to the first library with automatically link to its source + library as well. - - - If you don't want shared libraries to include all libraries - that are specified in sources (especially statically linked ones), - you'd need to use the following: + + On the other hand, when a shared library has a static library defined as + its source then the first library will be built so that it completely + includes the second one. + + + If you do not want shared libraries to include all libraries specified + in its sources (especially statically linked ones), you would need to + use the following: lib b : a.cpp ; lib a : a.cpp : <use>b : : <library>b ; - This specifies that a uses b, and causes - all executables that link to a also link to - b. In this case, even for shared linking, the - a library won't even refer to b. - - - -
- -
- Alias - - - The alias rule gives an alternative name to - a group of targets. For example, to give the name - core to a group of three other targets with the - following code: - -alias core : im reader writer ; - Using core on the command line, or in the source - list of any other target is the same as explicitly using - im, reader, and - writer, but it is just more convenient. + This specifies that library a uses library b, + and causes all executables that link to a also link to + b. In this case, even for shared linking, the + a library will not even refer to b. + + + One Boost.Build feature that is often very useful for defining library + targets are usage requirements. For example, imagine that + you want you build a helpers library and its interface is + described in its helpers.hpp header file located in the same + directory as the helpers.cpp source file. Then you could add + the following to the Jamfile located in that same directory: + +lib helpers : helpers.cpp : : : <include>. ; + + which would automatically add the directory where the target has been + defined (and where the library's header file is located) to the compiler's + include path for all targets using the helpers library. This + feature greatly simplifies Jamfiles. + +
- - Another use of the alias rule is to change build - properties. For example, if you always want static linking for a - specific C++ Boost library, you can write the following: +
+ Alias + + + The alias rule gives an alternative name to a + group of targets. For example, to give the name core + to a group of three other targets with the following code: + +alias core : im reader writer ; + + Using core on the command line, or in the source list + of any other target is the same as explicitly using im + , reader, and writer. + + + + Another use of the alias rule is to change build properties. + For example, if you want to use link statically to the Boost Threads + library, you can write the following: alias threads : /boost/thread//boost_thread : <link>static ; - and use only the threads alias in your Jamfiles. - + and use only the threads alias in your Jamfiles. + - - You can also specify usage requirements for the - alias target. If you write the following: + + You can also specify usage requirements for the alias target. + If you write the following: alias header_only_library : : : : <include>/usr/include/header_only_library ; - then using header_only_library in sources will only add an - include path. Also note that when an alias has sources, their usage - requirements are propagated as well. For example: + then using header_only_library in sources will only add an + include path. Also note that when an alias has sources, their usage + requirements are propagated as well. For example: lib library1 : library1.cpp : : : <include>/library/include1 ; lib library2 : library2.cpp : : : <include>/library/include2 ; alias static_libraries : library1 library2 : <link>static ; exe main : main.cpp static_libraries ; - will compile main.cpp with additional includes - required for using the specified static libraries. - + will compile main.cpp with additional includes + required for using the specified static libraries. + +
-
+
+ Installing -
- Installing + + This section describes various ways to install built target and arbitrary + files. + - This section describes various ways to install built target - and arbitrary files. + Basic install - Basic install - - For installing a built target you should use the - install rule, which follows the common syntax. For - example: + + For installing a built target you should use the install + rule, which follows the + common syntax. For example: install dist : hello helpers ; - will cause the targets hello and helpers to - be moved to the dist directory, relative to - Jamfile's directory. The directory can - be changed with the location property: + will cause the targets hello and helpers to be + moved to the dist directory, relative to the + Jamfile's directory. The directory can be changed using the + location property: install dist : hello helpers : <location>/usr/bin ; - While you can achieve the same effect by changing the target name to - /usr/bin, using the location - property is better, because it allows you to use a mnemonic target - name. - + While you can achieve the same effect by changing the target name to + /usr/bin, using the location property is + better as it allows you to use a mnemonic target name. + - The location property is especially handy when the location - is not fixed, but depends on build variant or environment variables: + + The location property is especially handy when the location + is not fixed, but depends on the build variant or environment variables: -install dist : hello helpers : <variant>release:<location>dist/release - <variant>debug:<location>dist/debug ; +install dist : hello helpers : + <variant>release:<location>dist/release + <variant>debug:<location>dist/debug ; install dist2 : hello helpers : <location>$(DIST) ; - See also conditional - properties and environment variables - + See also conditional + properties and environment + variables + - Installing with all dependencies + Installing with all dependencies - - Specifying the names of all libraries to install can be boring. The - install allows you to specify only the top-level executable - targets to install, and automatically install all dependencies: + + Specifying the names of all libraries to install can be boring. The + install allows you to specify only the top-level executable + targets to install, and automatically install all dependencies: install dist : hello : <install-dependencies>on <install-type>EXE <install-type>LIB ; - will find all targets that hello depends on, and install - all of those which are either executables or libraries. More - specifically, for each target, other targets that were specified as - sources or as dependency properties, will be recursively found. One - exception is that targets referred with the use feature - are not considered, because that feature is typically used to refer to - header-only libraries. - If the set of target types is specified, only targets of that type - will be installed, otherwise, all found target will be installed. - + will find all targets that hello depends on, and install all + of those which are either executables or libraries. More specifically, for + each target, other targets that were specified as sources or as dependency + properties, will be recursively found. One exception is that targets + referred with the + use feature are not considered, as that feature is + typically used to refer to header-only libraries. If the set of target + types is specified, only targets of that type will be installed, + otherwise, all found target will be installed. + - Preserving Directory Hierarchy + Preserving Directory Hierarchy - install-source-root - By default, the install rules will stip paths from - it's sources. So, if sources include a/b/c.hpp, - the a/b part will be ignored. To make the - install rule preserve the directory hierarchy you need - to use the install-source-root feature to specify the - root of the hierarchy you are installing. Relative paths from that + install-source-root + + + By default, the install rule will strip paths from its + sources. So, if sources include a/b/c.hpp, the + a/b part will be ignored. To make the + install rule preserve the directory hierarchy you need to + use the <install-source-root> feature to specify + the root of the hierarchy you are installing. Relative paths from that root will be preserved. For example, if you write: - install headers : a/b/c.h : <location>/tmp <install-source-root>a ; - the a file named /tmp/b/c.h will be created. - + - The glob-tree rule - can be used to find all files below a given directory, making - it easy to install entire directory tree. + + The glob-tree rule can be + used to find all files below a given directory, making it easy to install + an entire directory tree. + - Installing into Several Directories + Installing into Several Directories - The alias - rule can be used when targets must be installed into several - directories: + + The alias rule can be + used when targets need to be installed into several directories: alias install : install-bin install-lib ; install install-bin : applications : /usr/bin ; @@ -340,178 +351,180 @@ install install-lib : helper : /usr/lib ; Because the install rule just copies targets, most free - features see the definition of "free" in - . - have no effect when used in requirements of the install rule. - The only two which matter are dependency - and, on Unix, - dll-path. + features see the definition of "free" in . have no + effect when used in requirements of the install rule. The + only two that matter are + dependency and, on Unix, dll-path + . - (Unix specific). On Unix, executables built with Boost.Build typically - contain the list of paths to all used dynamic libraries. For installing, + (Unix specific) On Unix, executables built using Boost.Build typically + contain the list of paths to all used shared 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 dll-path feature. + executables using the dll-path feature. +
-
+
+ Testing -
- - Testing - - - Boost.Build has convenient support for running unit tests. The simplest - way is the unit-test rule, which follows the common syntax. For - example: + + Boost.Build has convenient support for running unit tests. The simplest + way is the unit-test rule, which follows the common syntax. For example: unit-test helpers_test : helpers_test.cpp helpers ; - + - The unit-test rule behaves like the - exe rule, but after the executable is created it is - run. If the executable returns an error code, the build system will also - return an error and will try running the executable on the next - invocation until it runs successfully. This behaviour ensures that you - can't miss a unit test failure. - + + The unit-test rule behaves like the + exe rule, but after the executable is created + it is also run. If the executable returns an error code, the build system + will also return an error and will try running the executable on the next + invocation until it runs successfully. This behaviour ensures that you can + not miss a unit test failure. + - By default, the executable is run directly. Sometimes, it's - desirable to run the executable using some helper command. You should use the - testing.launcher property to specify the name of the - helper command. For example, if you write: - + + By default, the executable is run directly. Sometimes, it is desirable to + run the executable using some helper command. You should use the + testing.launcher property to specify the name of the helper + command. For example, if you write: unit-test helpers_test : helpers_test.cpp helpers : <testing.launcher>valgrind ; - The command used to run the executable will be: + The command used to run the executable will be: valgrind bin/$toolset/debug/helpers_test + - There are few specialized testing rules, listed below: - + + There are few specialized testing rules, listed below: + rule compile ( sources : requirements * : target-name ? ) rule compile-fail ( sources : requirements * : target-name ? ) rule link ( sources + : requirements * : target-name ? ) rule link-fail ( sources + : requirements * : target-name ? ) - - 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 compile* - tests try to compile the passed source. The link* - rules try to compile and link an application from all the passed sources. - The compile and link rules expect - that compilation/linking succeeds. The compile-fail - and link-fail rules, on the opposite, expect that + + They 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 + compile* tests try to compile the passed source. The + link* rules try to compile and link an application from + all the passed sources. The compile and link + rules expect that compilation/linking succeeds. The + compile-fail and link-fail rules expect that the compilation/linking fails. - + - There are two specialized rules for running applications, which - are more powerful than the unit-test rule. The - run rule has the following signature: - + + There are two specialized rules for running applications, which are more + powerful than the unit-test rule. The run rule + has the following signature: + rule run ( sources + : args * : input-files * : requirements * : target-name ? : default-build * ) - - The rule builds application from the provided sources and runs it, - passing args and input-files - as command-line arguments. The args parameter - is passed verbatim and the values of the input-files - parameter are treated as paths relative to containing Jamfile, and are - adjusted if bjam is invoked from a different - directory. The run-fail rule is identical to the - run rule, except that it expects that the run fails. - + + The rule builds application from the provided sources and runs it, passing + args and input-files as command-line + arguments. The args parameter is passed verbatim and + the values of the input-files parameter are treated as + paths relative to containing Jamfile, and are adjusted if bjam + is invoked from a different directory. The + run-fail rule is identical to the run rule, + except that it expects that the run fails. + - All rules described in this section, if executed successfully, - create a special manifest file to indicate that the test passed. - For the unit-test rule the files is named - target-name.passed and - for the other rules it is called - target-name.test. - The run* rules also capture all output from the program, - and store it in a file named - target-name.output. + + All rules described in this section, if executed successfully, create a + special manifest file to indicate that the test passed. For the + unit-test rule the files is named + target-name.passed and for the other rules it is + called target-name.test. + The run* rules also capture all output from the program, and + store it in a file named + target-name.output. + - The run and the run-fail rules, if - the test passes, automatically delete the linked executable, to - save space. This behaviour can be suppressed by passing the - --preserve-test-targets command line option. + + The run and the run-fail rules, if the test + passes, automatically delete the linked executable, to save space. This + behaviour can be suppressed by passing the + --preserve-test-targets command line option. + - It is possible to print the list of all test targets (except for - unit-test) declared in your project, by passing - the --dump-tests command-line option. The output - will consist of lines of the form: - + + It is possible to print the list of all test targets (except for + unit-test) declared in your project, by passing the + --dump-tests command-line option. The output will consist of + lines of the form: + boost-test(test-type) path : sources - - + + - It is possible to process the list of tests, the output of - bjam during command run, and the presense/absense of the - *.test files created when test passes into - human-readable status table of tests. Such processing utilities - are not included in Boost.Build. + + It is possible to process the list of tests, the output of bjam during + command run, and the presense/absense of the *.test + files created when test passes into human-readable status table of tests. + Such processing utilities are not included in Boost.Build. + +
-
+
+ Custom commands -
+ + 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 . + However, if there is only a single place where the new tool is used, it + might be easier to just explicitly specify the commands to run. + - Custom commands + + + Three main target rules can be used for that. The make + rule allows you to construct a single file from any number + of source file, by running a command you specify. The + notfile rule allows you to run an arbitrary command, + without creating any files. And finaly, the generate + 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, create differently named targets depending on + properties or use more than one tool. + - - 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 - . 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. - + + The make rule is used when you want to create + one file from a number of sources using some specific command. The + notfile is used to unconditionally run a + command. + - - - Three main target rules can be used for that. The make - rule allows you to construct a single file from any - number of source file, by running a command you specify. The - notfile rule allows you to run an arbitrary - command, without creating any files. And finaly, the - generate 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, create differently named targets - depending on properties or use more than one tool. - + - - The make rule is used when you want to - create one file from a number of sources using some specific command. - The notfile is used to unconditionally run - a command. - - - - - - Suppose you want to create file file.out from file - file.in by running command - in2out. Here is how you would do this in Boost.Build: + + Suppose you want to create file file.out from file + file.in by running command + in2out. Here is how you would do this in Boost.Build: make file.out : file.in : @in2out ; actions in2out @@ -519,16 +532,16 @@ actions in2out in2out $(<) $(>) } - If you run bjam and file.out - does not exist, Boost.Build will run the in2out - command to create that file. For more details on specifying actions, see - . - + If you run bjam and file.out does + not exist, Boost.Build will run the in2out command to + create that file. For more details on specifying actions, see . + - - 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 notfile rule. For example: + + 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 + notfile rule. For example: notfile echo_something : @echo ; actions echo @@ -536,56 +549,56 @@ actions echo echo "something" } - The only difference from the make rule is - that the name of the target is not considered a name of a file, so - Boost.Build will unconditionally run the action. - + The only difference from the make rule is + that the name of the target is not considered a name of a file, so + Boost.Build will unconditionally run the action. + - - - The generate rule is used when you want to - express transformations using Boost.Build's virtual targets, as opposed - to just filenames. The generate rule has - the standard main target rule signature, but you are required to specify - the generating-rule property. The value of the - property should be in the form - @rule-name, the named rule - should have the following signature: + + + The generate rule is used when you want to + express transformations using Boost.Build's virtual targets, as opposed to + just filenames. The generate rule has the + standard main target rule signature, but you are required to specify the + generating-rule property. The value of the property + should be in the form + @rule-name, the named rule should + have the following signature: rule generating-rule ( project name : property-set : sources * ) - and will be called with an instance of the project-target - class, the name of the main target, an instance of the - property-set class containing build properties, and the - list of instances of the virtual-target class corresponding - to sources. The rule must return a list of virtual-target - instances. The interface of the virtual-target class can be - learned by looking at the build/virtual-target.jam - file. The generate example contained in the - Boost.Build distribution illustrates how the generate - rule can be used. - + and will be called with an instance of the project-target + class, the name of the main target, an instance of the + property-set class containing build properties, and the list + of instances of the virtual-target class corresponding to + sources. The rule must return a list of virtual-target + instances. The interface of the virtual-target class can be + learned by looking at the build/virtual-target.jam + file. The generate example contained in the + Boost.Build distribution illustrates how the generate + rule can be used. + +
-
+
+ Precompiled Headers -
- Precompiled Headers + + 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. + - - 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. - + + To use precompiled headers, follow the following steps: + - - To use precompiled headers, follow the following steps: - - - - + + + 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 @@ -593,9 +606,11 @@ rule generating-rule ( project name : property-set : sources * ) BOOST_BUILD_PCH_ENABLED, 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. - + + - + + 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: @@ -606,91 +621,99 @@ exe main : main.cpp pch ; You can use the c-pch rule if you want to use the precompiled header in C programs. - + - - The pch example in Boost.Build distribution can be - used as reference. - + + The pch example in Boost.Build distribution can be + used as reference. + - - Please note the following: - + + Please note the following: + - - + + + The inclusion of the precompiled header must be the first thing in a source file, before any code or preprocessor directives. - + + - + + The build properties used to compile the source files and the precompiled header must be the same. Consider using project requirements to assure this. - + + - + + Precompiled headers must be used purely as a way to improve compilation time, not to save the number of #include 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. - + + - + + On the gcc compiler, the name of the header being precompiled must be equal to the name of the cpp-pch target. This is a gcc requirement. - + + - + + Prior to version 4.2, the gcc compiler did not allow anonymous namespaces in precompiled headers, which limits their utility. See the - bug + bug report for details. - - -
+ + + +
-
- Generated headers +
+ Generated headers - Usually, Boost.Build handles implicit dependendies completely - automatically. For example, for C++ files, all #include - statements are found and handled. The only aspect where user help - might be needed is implicit dependency on generated files. + + Usually, Boost.Build handles implicit dependendies completely + automatically. For example, for C++ files, all #include + statements are found and handled. The only aspect where user help might be + needed is implicit dependency on generated files. + - 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 - into "parser.c" and "parser.h". Then, if "app.cpp" includes - "parser.h", Boost.Build will detect this dependency. Moreover, - since "parser.h" will be generated into a build directory, the - path to that directory will automatically added to include - path. - - 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 - <implicit-dependency> [ link ] feature must - be used, for example: + + 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 into "parser.c" and "parser.h". + Then, if "app.cpp" includes "parser.h", Boost.Build will detect this + dependency. Moreover, since "parser.h" will be generated into a build + directory, the path to that directory will automatically added to include + path. + + + Making this mechanism work across main target boundaries is possible, but + imposes certain overhead. For that reason, if there is implicit dependency + on files from other main targets, the <implicit-dependency> + [ link ] feature must be used, for example: lib parser : parser.y ; exe app : app.cpp : <implicit-dependency>parser ; - - - The above example tells the build system that when scanning - all sources of "app" for implicit-dependencies, it should consider - targets from "parser" as potential dependencies. - -
- + The above example tells the build system that when scanning all sources of + "app" for implicit-dependencies, it should consider targets from "parser" + as potential dependencies. + +
- -
  • Bug tracker +
  • Bug tracker

    diff --git a/v2/kernel/modules.jam b/v2/kernel/modules.jam index 586336736..1f75354fc 100644 --- a/v2/kernel/modules.jam +++ b/v2/kernel/modules.jam @@ -242,11 +242,13 @@ rule import ( module-names + : rules-opt * : rename-opt * ) { if ( $(rules-opt) = * || ! $(rules-opt) ) && $(rename-opt) { + import errors ; errors.error "Rule aliasing is only available for explicit imports." ; } if $(module-names[2]) && ( $(rules-opt) || $(rename-opt) ) { + import errors ; errors.error "When loading multiple modules, no specific rules or" "renaming is allowed" ; } diff --git a/v2/nightly.sh b/v2/nightly.sh index c93eb29e6..7b6c85c6a 100755 --- a/v2/nightly.sh +++ b/v2/nightly.sh @@ -25,5 +25,5 @@ echo "Building packages and uploading docs" ./roll.sh > ../roll-log 2>&1 cd .. echo "Uploading packages" -scp boost-build.zip boost-build.tar.bz2 vladimir_prus@shell.sourceforge.net:/home/groups/b/bo/boost/htdocs/boost-build2 > scp-log +scp boost-build.zip boost-build.tar.bz2 vladimir_prus,boost@web.sourceforge.net:/home/groups/b/bo/boost/htdocs/boost-build2 > scp-log echo "Nightly build successful" diff --git a/v2/roll.sh b/v2/roll.sh index 5bbc4af69..7569ac1ef 100755 --- a/v2/roll.sh +++ b/v2/roll.sh @@ -26,7 +26,7 @@ rm -rf example/versioned find . -maxdepth 1 -type f | egrep -v "boost-build.jam|timestamp.txt|roll.sh|bootstrap.jam|build-system.jam|boost_build.png|index.html|hacking.txt|site-config.jam|user-config.jam" | xargs rm -f # Build the documentation -touch doc/project-root.jam +touch doc/jamroot.jam export BOOST_BUILD_PATH=`pwd` cd doc /home/ghost/Work/Boost/boost-svn/tools/jam/src/bin.linuxx86/bjam --v2 @@ -65,5 +65,5 @@ urchinTracker(); EOF` echo $x perl -pi -e "s||$x|" `find doc -name '*.html'` -scp -r doc example boost_build.png *.html hacking.txt vladimir_prus@shell.sourceforge.net:/home/groups/b/bo/boost/htdocs/boost-build2 -scp ../userman.pdf vladimir_prus@shell.sourceforge.net:/home/groups/b/bo/boost/htdocs/boost-build2/doc +scp -r doc example boost_build.png *.html hacking.txt vladimir_prus,boost@web.sourceforge.net:/home/groups/b/bo/boost/htdocs/boost-build2 +scp ../userman.pdf vladimir_prus,boost@web.sourceforge.net:/home/groups/b/bo/boost/htdocs/boost-build2/doc diff --git a/v2/test/BoostBuild.py b/v2/test/BoostBuild.py index 199f586d2..dc9974a41 100644 --- a/v2/test/BoostBuild.py +++ b/v2/test/BoostBuild.py @@ -67,7 +67,7 @@ def get_toolset(): # Detect the host OS. windows = False -if os.environ.get('OS','').lower().startswith('windows') or \ +if os.environ.get('OS', '').lower().startswith('windows') or \ os.__dict__.has_key('uname') and \ os.uname()[0].lower().startswith('cygwin'): windows = True @@ -88,13 +88,13 @@ def prepare_suffix_map(toolset): suffixes['.lib'] = '.a' # static libs have '.a' suffix with mingw... suffixes['.obj'] = '.o' suffixes['.implib'] = '.lib' - if os.__dict__.has_key('uname') and os.uname()[0] == 'Darwin': + if os.__dict__.has_key('uname') and (os.uname()[0] == 'Darwin'): suffixes['.dll'] = '.dylib' def re_remove(sequence, regex): me = re.compile(regex) - result = filter( lambda x: me.match(x), sequence ) + result = filter(lambda x: me.match(x), sequence) if 0 == len(result): raise ValueError() for r in result: @@ -102,7 +102,7 @@ def re_remove(sequence, regex): def glob_remove(sequence, pattern): - result = fnmatch.filter(sequence,pattern) + result = fnmatch.filter(sequence, pattern) if 0 == len(result): raise ValueError() for r in result: @@ -206,7 +206,7 @@ class Tester(TestCmd.TestCmd): jam_build_dir = "" if os.name == 'nt': jam_build_dir = "bin.ntx86" - elif os.name == 'posix' and os.__dict__.has_key('uname'): + elif (os.name == 'posix') and os.__dict__.has_key('uname'): if os.uname()[0].lower().startswith('cygwin'): jam_build_dir = "bin.cygwinx86" if 'TMP' in os.environ and os.environ['TMP'].find('~') != -1: @@ -238,7 +238,7 @@ class Tester(TestCmd.TestCmd): else: raise "Don't know directory where Jam is built for this system: " + os.name - # Find where jam_src is located. Try for the debug version if it's + # Find where jam_src is located. Try for the debug version if it is # lying around. dirs = [os.path.join('../../../jam/src', jam_build_dir + '.debug'), os.path.join('../../../jam/src', jam_build_dir), @@ -445,7 +445,7 @@ class Tester(TestCmd.TestCmd): finally: self.last_build_time_finish = time.time() - if status != None and _failed(self, status): + if (status != None) and _failed(self, status): expect = '' if status != 0: expect = " (expected %d)" % status @@ -456,7 +456,7 @@ class Tester(TestCmd.TestCmd): annotation("reason", "error returned by bjam") self.fail_test(1) - if not stdout is None and not match(self.stdout(), stdout): + if not (stdout is None) and not match(self.stdout(), stdout): annotation("failure", "Unexpected stdout") annotation("Expected STDOUT", stdout) annotation("Actual STDOUT", self.stdout()) @@ -470,7 +470,7 @@ class Tester(TestCmd.TestCmd): intel_workaround = re.compile("^xi(link|lib): executing.*\n", re.M) actual_stderr = re.sub(intel_workaround, "", self.stderr()) - if not stderr is None and not match(actual_stderr, stderr): + if not (stderr is None) and not match(actual_stderr, stderr): annotation("failure", "Unexpected stderr") annotation("Expected STDERR", stderr) annotation("Actual STDERR", self.stderr()) @@ -480,7 +480,7 @@ class Tester(TestCmd.TestCmd): if not expected_duration is None: actual_duration = self.last_build_time_finish - self.last_build_time_start - if ( actual_duration > expected_duration ): + 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) @@ -493,9 +493,9 @@ class Tester(TestCmd.TestCmd): def glob_file(self, name): result = None - if hasattr(self,'difference'): + if hasattr(self, 'difference'): for f in self.difference.added_files+self.difference.modified_files+self.difference.touched_files: - if fnmatch.fnmatch(f,name): + if fnmatch.fnmatch(f, name): result = self.native_file_name(f) break if not result: @@ -510,7 +510,7 @@ class Tester(TestCmd.TestCmd): name = string.replace(name, "$toolset", self.toolset+"*") name = self.glob_file(name) openMode = "r" - if ( binary ): + if binary: openMode += "b" else: openMode += "U" @@ -564,7 +564,7 @@ class Tester(TestCmd.TestCmd): def expect_addition(self, names): for name in self.adjust_names(names): try: - glob_remove(self.unexpected_difference.added_files,name) + glob_remove(self.unexpected_difference.added_files, name) except: print "File %s not added as expected" % name self.fail_test(1) @@ -575,7 +575,7 @@ class Tester(TestCmd.TestCmd): def expect_removal(self, names): for name in self.adjust_names(names): try: - glob_remove(self.unexpected_difference.removed_files,name) + glob_remove(self.unexpected_difference.removed_files, name) except: print "File %s not removed as expected" % name self.fail_test(1) @@ -586,13 +586,14 @@ class Tester(TestCmd.TestCmd): def expect_modification(self, names): for name in self.adjust_names(names): try: - glob_remove(self.unexpected_difference.modified_files,name) + glob_remove(self.unexpected_difference.modified_files, name) except: print "File %s not modified as expected" % name self.fail_test(1) def ignore_modification(self, wildcard): - self.ignore_elements(self.unexpected_difference.modified_files, wildcard) + self.ignore_elements(self.unexpected_difference.modified_files, \ + wildcard) def expect_touch(self, names): d = self.unexpected_difference @@ -607,7 +608,7 @@ class Tester(TestCmd.TestCmd): while filesets: try: - glob_remove(filesets[-1],name) + glob_remove(filesets[-1], name) break except ValueError: filesets.pop() @@ -646,7 +647,7 @@ class Tester(TestCmd.TestCmd): self.fail_test(1) def expect_nothing_more(self): - # Not totally sure about this change, but I don't see a good + # Not totally sure about this change, but I do not see a good # alternative. if windows: self.ignore('*.ilk') # MSVC incremental linking files. @@ -676,12 +677,12 @@ class Tester(TestCmd.TestCmd): break if expected_to_exist and not found: - annotation( "failure", + annotation("failure", "Did not find expected line:\n%s\nin output:\n%s" % (expected, content)) self.fail_test(1) if not expected_to_exist and found: - annotation( "failure", + annotation("failure", "Found an unexpected line:\n%s\nin output:\n%s" % (expected, content)) self.fail_test(1) @@ -712,22 +713,22 @@ class Tester(TestCmd.TestCmd): matched = False if exact: - matched = fnmatch.fnmatch(actual,content) + matched = fnmatch.fnmatch(actual, content) else: 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()) + 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), - actual_, content_ ) + lambda x, y: map(lambda n, p: fnmatch.fnmatch(n, p), x, y), + actual_, content_) matched = reduce( - lambda x,y: x and reduce( - lambda a,b: a and b, - y ), - matched ) + lambda x, y: x and reduce( + lambda a, b: a and b, + y), + matched) if not matched: print "Expected:\n" @@ -744,7 +745,7 @@ class Tester(TestCmd.TestCmd): open(a, "w").write(actual) print "DIFFERENCE" if os.system("diff -u " + e + " " + a): - print "Unable to compute difference: diff -u %s %s" % (e,a) + print "Unable to compute difference: diff -u %s %s" % (e, a) os.unlink(e) os.unlink(a) else: @@ -793,7 +794,7 @@ class Tester(TestCmd.TestCmd): tail = "lib" + tail result = os.path.join(head, tail) # If we want to use this name in a Jamfile, we better convert \ to /, as - # otherwise we'd have to quote \. + # otherwise we would have to quote \. result = string.replace(result, "\\", "/") return result @@ -873,7 +874,7 @@ class List: return str(self.l) def __repr__(self): - return ( self.__module__ + '.List(' + return (self.__module__ + '.List(' + repr(string.join(self.l, ' ')) + ')') diff --git a/v2/test/abs_workdir.py b/v2/test/abs_workdir.py index f0860f154..29fab06fa 100644 --- a/v2/test/abs_workdir.py +++ b/v2/test/abs_workdir.py @@ -1,6 +1,6 @@ # Niklaus Giger, 2005-03-15 -# Testing whether we may run a test in a absolute directories -# There are no tests for temporary directories as this is implictly tested in a lot of other cases +# Testing whether we may run a test in absolute directories. There are no tests +# for temporary directories as this is implictly tested in a lot of other cases. import BoostBuild import os @@ -9,10 +9,10 @@ import string t = BoostBuild.Tester(arguments="pwd", executable="jam", workdir=os.getcwd(), pass_toolset=0) -t.write("Jamroot.jam", """ +t.write("jamroot.jam", """ actions print_pwd { pwd ; } print_pwd pwd ; -Always pwd ; +ALWAYS pwd ; """) t.run_build_system(status=0) @@ -30,5 +30,5 @@ if string.rfind(t.stdout(), 'build/v2/test') == -1: t.run_build_system(status=1, subdir="/must/fail/with/absolute/path", stderr=None) -t.cleanup +t.cleanup() diff --git a/v2/test/absolute_sources.py b/v2/test/absolute_sources.py index cd658765e..eca8d5ad2 100644 --- a/v2/test/absolute_sources.py +++ b/v2/test/absolute_sources.py @@ -1,72 +1,76 @@ #!/usr/bin/python -# Copyright 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, 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) # Test that sources with absolute names are handled OK. -from BoostBuild import Tester -t = Tester() +import BoostBuild -t.write("project-root.jam", """ +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ path-constant TOP : . ; """) -t.write("Jamfile", """ + +t.write("jamfile.jam", """ local pwd = [ PWD ] ; ECHO $(pwd) XXXXX ; exe hello : $(pwd)/hello.cpp $(TOP)/empty.cpp ; """) -t.write("hello.cpp", "int main() { return 0; }\n") + +t.write("hello.cpp", "int main() {}\n") + t.write("empty.cpp", "\n") t.run_build_system() t.expect_addition("bin/$toolset/debug/hello.exe") -# Test a contrived case. There, absolute name is used in -# standalone project (not Jamfile). Moreover, the target with -# absolute name is returned by 'alias' and used from other project. -t.write("a.cpp", """ -int main() -{ - return 0; -} - +# Test a contrived case. There, absolute name is used in a standalone project +# (not Jamfile). Moreover, the target with an absolute name is returned by +# 'alias' and used from another project. +t.write("a.cpp", """ +int main() {} """) -t.write("Jamfile", """ -exe a : /standalone//a ; +t.write("jamfile.jam", """ +exe a : /standalone//a ; """) -t.write("project-root.jam", """ -import standalone ; +t.write("jamroot.jam", """ +import standalone ; """) -t.write("standalone.jam", """ +t.write("standalone.jam", """ import project ; project.initialize $(__name__) ; project standalone ; local pwd = [ PWD ] ; - alias a : $(pwd)/a.cpp ; - """) + t.run_build_system() t.expect_addition("bin/$toolset/debug/a.exe") -# Test absolute path in target ids +# Test absolute path in target ids. t.rm(".") -t.write("d1/project-root.jam", "") -t.write("d1/Jamfile", """ + +t.write("d1/jamroot.jam", "") + +t.write("d1/jamfile.jam", """ exe a : a.cpp ; """) + t.write("d1/a.cpp", """ -int main() { return 0; } +int main() {} """) -t.write("d2/project-root.jam", "") -t.write("d2/Jamfile", """ + +t.write("d2/jamroot.jam", "") + +t.write("d2/jamfile.jam", """ local pwd = [ PWD ] ; alias x : $(pwd)/../d1//a ; """) diff --git a/v2/test/alias.py b/v2/test/alias.py index a4cfef63d..107b12e87 100644 --- a/v2/test/alias.py +++ b/v2/test/alias.py @@ -5,7 +5,7 @@ # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) -from BoostBuild import Tester, List +import BoostBuild ################################################################################ @@ -19,7 +19,7 @@ def test_alias_rule(t): """Basic alias rule test. """ - t.write("Jamroot.jam", """ + t.write("jamroot.jam", """ exe a : a.cpp ; exe b : b.cpp ; exe c : c.cpp ; @@ -31,7 +31,7 @@ alias src : s.cpp ; exe hello : hello.cpp src ; """) - t.write("a.cpp", "int main() { return 0; }\n") + t.write("a.cpp", "int main() {}\n") t.copy("a.cpp", "b.cpp") t.copy("a.cpp", "c.cpp") t.copy("a.cpp", "hello.cpp") @@ -39,19 +39,20 @@ exe hello : hello.cpp src ; # Check that targets to which "bin1" refers are updated, and only those. t.run_build_system("bin1") - t.expect_addition(List("bin/$toolset/debug/") * "a.exe a.obj") + t.expect_addition(BoostBuild.List("bin/$toolset/debug/") * "a.exe a.obj") t.expect_nothing_more() # Try again with "bin2" t.run_build_system("bin2") - t.expect_addition(List("bin/$toolset/debug/") * "b.exe b.obj") + t.expect_addition(BoostBuild.List("bin/$toolset/debug/") * "b.exe b.obj") t.expect_nothing_more() # Try building everything, making sure 'hello' target is created. t.run_build_system() - t.expect_addition(List("bin/$toolset/debug/") * "hello.exe hello.obj") + t.expect_addition(BoostBuild.List("bin/$toolset/debug/") * \ + "hello.exe hello.obj") t.expect_addition("bin/$toolset/debug/s.obj") - t.expect_addition(List("bin/$toolset/debug/") * "c.exe c.obj") + t.expect_addition(BoostBuild.List("bin/$toolset/debug/") * "c.exe c.obj") t.expect_nothing_more() @@ -68,7 +69,7 @@ def test_alias_source_usage_requirements(t): anywhere in the source. """ - t.write("Jamroot.jam", """ + t.write("jamroot.jam", """ lib l : l.cpp : : : WANT_MAIN ; alias la : l ; exe main : main.cpp la ; @@ -84,7 +85,7 @@ foo() {} t.write("main.cpp", """ #ifdef WANT_MAIN -int main() { return 0; } +int main() {} #endif """) @@ -98,7 +99,7 @@ int main() { return 0; } # ################################################################################ -t = Tester() +t = BoostBuild.Tester() test_alias_rule(t) test_alias_source_usage_requirements(t) diff --git a/v2/test/alternatives.py b/v2/test/alternatives.py index 9d10c6f1d..6d423212f 100644 --- a/v2/test/alternatives.py +++ b/v2/test/alternatives.py @@ -1,42 +1,44 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# Copyright 2003, 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, 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) # Test main target alternatives. -from BoostBuild import Tester -from string import find -t = Tester() +import BoostBuild +import string +t = BoostBuild.Tester() # Test that basic alternatives selection works. -t.write("project-root.jam", " ") -t.write("Jamfile", """ +t.write("jamroot.jam", "") +t.write("jamfile.jam", """ exe a : a_empty.cpp ; exe a : a.cpp : release ; """) + t.write("a_empty.cpp", "") -t.write("a.cpp", "int main() { return 0; }\n") + +t.write("a.cpp", "int main() {}\n") t.run_build_system("release") + t.expect_addition("bin/$toolset/release/a.exe") -# Test that alternative selection works for ordinary -# properties, in particular user-defined. -t.write("project-root.jam", " ") -t.write("Jamfile", """ +# Test that alternative selection works for ordinary properties, in particular +# user-defined. +t.write("jamroot.jam", "") +t.write("jamfile.jam", """ import feature ; feature.feature X : off on : propagated ; - exe a : b.cpp ; exe a : a.cpp : on ; """) -t.write("b.cpp", "int main() { return 0; }\n") +t.write("b.cpp", "int main() {}\n") t.rm("bin") @@ -48,11 +50,8 @@ t.expect_addition("bin/$toolset/debug/X-on/a.obj") t.rm("bin") -# Test that everything works ok even with default -# build. - -t.write("Jamfile", """ - +# Test that everything works ok even with default build. +t.write("jamfile.jam", """ exe a : a_empty.cpp : release ; exe a : a.cpp : debug ; """) @@ -60,12 +59,10 @@ exe a : a.cpp : debug ; t.run_build_system() t.expect_addition("bin/$toolset/debug/a.exe") -# Test that only properties which are in build request -# matters when selection alternative. IOW, alternative -# with release is better than one with +# Test that only properties which are in build request matter for alternative +# selection. IOW, alternative with release is better than one with # debug when building release version. -t.write("Jamfile", """ - +t.write("jamfile.jam", """ exe a : a_empty.cpp : debug ; exe a : a.cpp : release ; """) @@ -73,10 +70,9 @@ exe a : a.cpp : release ; t.run_build_system("release") t.expect_addition("bin/$toolset/release/a.exe") -# Test that free properties do not matter. We really don't -# want property in build request to affect -# alternative selection. -t.write("Jamfile", """ +# Test that free properties do not matter. We really do not want +# property in build request to affect alternative selection. +t.write("jamfile.jam", """ exe a : a_empty.cpp : debug FOO BAR ; exe a : a.cpp : release ; """) @@ -85,28 +81,26 @@ t.rm("bin/$toolset/release/a.exe") t.run_build_system("release define=FOO") t.expect_addition("bin/$toolset/release/a.exe") -# Test that abibuity is reported correctly -t.write("Jamfile", """ +# Test that ambiguity is reported correctly. +t.write("jamfile.jam", """ exe a : a_empty.cpp ; exe a : a.cpp ; """) t.run_build_system("--no-error-backtrace", status=None) -t.fail_test(find(t.stdout(), "No best alternative") == -1) +t.fail_test(string.find(t.stdout(), "No best alternative") == -1) -# Another ambiguity test: two matches properties in one alternative are -# neither better nor worse than a single one in another alternative. -t.write("Jamfile", """ +# Another ambiguity test: two matches properties in one alternative are neither +# better nor worse than a single one in another alternative. +t.write("jamfile.jam", """ exe a : a_empty.cpp : off off ; exe a : a.cpp : on ; """) t.run_build_system("--no-error-backtrace", status=None) -t.fail_test(find(t.stdout(), "No best alternative") == -1) +t.fail_test(string.find(t.stdout(), "No best alternative") == -1) - - -# Test that we can have alternative without sources -t.write("Jamfile", """ +# Test that we can have alternative without sources. +t.write("jamfile.jam", """ alias specific-sources ; import feature ; feature.extend os : MAGIC ; @@ -116,5 +110,4 @@ exe a : a.cpp specific-sources ; t.rm("bin") t.run_build_system() - -t.cleanup() +t.cleanup() diff --git a/v2/test/bad_dirname.py b/v2/test/bad_dirname.py index c6c2ead49..961a45a48 100644 --- a/v2/test/bad_dirname.py +++ b/v2/test/bad_dirname.py @@ -1,23 +1,22 @@ #!/usr/bin/python -# 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) +# 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) -# Regression test: when directory of project root contained regex metacharacters, -# Boost.Build failed to work. Bug reported by Michael Stevens +# Regression test: when directory of project root contained regex +# metacharacters, Boost.Build failed to work. Bug reported by Michael Stevens. -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("bad[abc]dirname/Jamfile", """ +t.write("bad[abc]dirname/jamfile.jam", """ """) -t.write("bad[abc]dirname/project-root.jam", """ +t.write("bad[abc]dirname/jamroot.jam", """ """) t.run_build_system(subdir="bad[abc]dirname") t.cleanup() - diff --git a/v2/test/boostbook.py b/v2/test/boostbook.py index 703002bd1..78eab87d0 100644 --- a/v2/test/boostbook.py +++ b/v2/test/boostbook.py @@ -1,16 +1,16 @@ #!/usr/bin/python -# Copyright 2004, 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, 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) -from BoostBuild import Tester, List +import BoostBuild import string -# Create a temporary working directory -t = Tester() +t = BoostBuild.Tester() t.set_tree("boostbook") + # For some reason, the messages are sent to stderr. t.run_build_system() t.fail_test(string.find(t.stdout(), """Writing boost/A.html for refentry(boost.A) diff --git a/v2/test/boostbook/Jamroot b/v2/test/boostbook/jamroot.jam similarity index 100% rename from v2/test/boostbook/Jamroot rename to v2/test/boostbook/jamroot.jam diff --git a/v2/test/build_dir.py b/v2/test/build_dir.py index 3b953d284..efdd522a4 100644 --- a/v2/test/build_dir.py +++ b/v2/test/build_dir.py @@ -1,55 +1,52 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# Copyright 2002, 2003, 2005 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, 2005 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) -# Test that we can change build directory using -# the 'build-dir' project attribute. +# Test that we can change build directory using the 'build-dir' project +# attribute. -from BoostBuild import Tester +import BoostBuild import string import os -t = Tester() +t = BoostBuild.Tester() -# Test that top-level project can affect build dir -t.write("project-root.jam", "import gcc ; ") -t.write("Jamfile", """ -project - : build-dir build - ; - +# Test that top-level project can affect build dir. +t.write("jamroot.jam", "import gcc ;") +t.write("jamfile.jam", """ +project : build-dir build ; exe a : a.cpp ; -build-project src ; +build-project src ; """) -t.write("a.cpp", "int main() { return 0; }\n") -t.write("src/Jamfile", "exe b : b.cpp ; ") -t.write("src/b.cpp", "int main() { return 0; }\n") +t.write("a.cpp", "int main() {}\n") + +t.write("src/jamfile.jam", "exe b : b.cpp ; ") + +t.write("src/b.cpp", "int main() {}\n") t.run_build_system() t.expect_addition(["build/$toolset/debug/a.exe", "build/src/$toolset/debug/b.exe"]) - -# Test that building from child projects work + +# Test that building from child projects work. t.run_build_system(subdir='src') -t.expect_nothing_more() - -# Test that project can override build dir -t.write("Jamfile", """ +t.expect_nothing_more() + +# Test that project can override build dir. +t.write("jamfile.jam", """ exe a : a.cpp ; build-project src ; -""") +""") -t.write("src/Jamfile", """ -project - : build-dir build - ; -exe b : b.cpp ; +t.write("src/jamfile.jam", """ +project : build-dir build ; +exe b : b.cpp ; """) t.run_build_system() @@ -58,46 +55,44 @@ t.expect_addition(["bin/$toolset/debug/a.exe", # Now test the '--build-dir' option. t.rm(".") -t.write("Jamroot", "") +t.write("jamroot.jam", "") # Test that we get an error when no project id is specified. t.run_build_system("--build-dir=foo") t.fail_test(string.find(t.stdout(), "warning: the --build-dir option will be ignored") == -1) -t.write("Jamroot", """ +t.write("jamroot.jam", """ project foo ; exe a : a.cpp ; build-project sub ; """) -t.write("a.cpp", "int main() { return 0; }\n") -t.write("sub/Jamfile", "exe b : b.cpp ;\n") -t.write("sub/b.cpp", "int main() { return 0; }\n") +t.write("a.cpp", "int main() {}\n") +t.write("sub/jamfile.jam", "exe b : b.cpp ;\n") +t.write("sub/b.cpp", "int main() {}\n") t.run_build_system("--build-dir=build") t.expect_addition(["build/foo/$toolset/debug/a.exe", "build/foo/sub/$toolset/debug/b.exe"]) -t.write("Jamroot", """ +t.write("jamroot.jam", """ project foo : build-dir bin.v2 ; exe a : a.cpp ; build-project sub ; """) t.run_build_system("--build-dir=build") -t.expect_addition(["build/foo/bin.v2/$toolset/debug/a.exe", +t.expect_addition(["build/foo/bin.v2/$toolset/debug/a.exe", "build/foo/bin.v2/sub/$toolset/debug/b.exe"]) -# Try building in subdir. We expect that the entire build -# tree with be in 'sub/build'. Today, I'm not sure if -# this is what the user expects, but let it be. +# Try building in subdir. We expect that the entire build tree with be in +# 'sub/build'. Today, I am not sure if this is what the user expects, but let it +# be. t.rm('build') t.run_build_system("--build-dir=build", subdir="sub") t.expect_addition(["sub/build/foo/bin.v2/sub/$toolset/debug/b.exe"]) - - -t.write("Jamroot", """ +t.write("jamroot.jam", """ project foo : build-dir %s ; exe a : a.cpp ; build-project sub ; @@ -105,9 +100,6 @@ build-project sub ; t.run_build_system("--build-dir=build", status=1) t.fail_test(string.find(t.stdout(), - "Absolute directory specified via 'build-dir' project attribute") == -1) + "Absolute directory specified via 'build-dir' project attribute") == -1) - - - -t.cleanup() +t.cleanup() diff --git a/v2/test/build_file.py b/v2/test/build_file.py index 9f602001f..609690fea 100644 --- a/v2/test/build_file.py +++ b/v2/test/build_file.py @@ -22,18 +22,18 @@ import BoostBuild def test_building_file_from_specific_project(): t = BoostBuild.Tester() - t.write("Jamroot.jam", """ + 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", """ + t.write("hello.cpp", "int main() {}") + 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() {}") t.run_build_system("sub " + t.adjust_suffix("hello.obj")) t.expect_output_line("*depends on itself*", False) @@ -53,14 +53,14 @@ exe sub : hello.cpp ; def test_building_file_from_specific_target(): t = BoostBuild.Tester() - t.write("Jamroot.jam", """ + 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.write("hello1.cpp", "int main() {}") + t.write("hello2.cpp", "int main() {}") + t.write("hello3.cpp", "int main() {}") t.run_build_system("hello1 " + t.adjust_suffix("hello1.obj")) t.expect_addition("bin/$toolset/debug/hello1.obj") @@ -79,17 +79,17 @@ exe hello3 : hello3.cpp ; def test_building_missing_file_from_specific_target(): t = BoostBuild.Tester() - t.write("Jamroot.jam", """ + 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.write("hello1.cpp", "int main() {}") + t.write("hello2.cpp", "int main() {}") + t.write("hello3.cpp", "int main() {}") 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_output_line("don't know how to make*" + t.adjust_suffix("hello2.obj")) t.expect_nothing_more() t.cleanup() @@ -105,14 +105,14 @@ exe hello3 : hello3.cpp ; def test_building_multiple_files_with_different_names(): t = BoostBuild.Tester() - t.write("Jamroot.jam", """ + 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.write("hello1.cpp", "int main() {}") + t.write("hello2.cpp", "int main() {}") + t.write("hello3.cpp", "int main() {}") t.run_build_system( t.adjust_suffix("hello1.obj") + " " + @@ -134,18 +134,18 @@ exe hello3 : hello3.cpp ; def test_building_multiple_files_with_the_same_name(): t = BoostBuild.Tester() - t.write("Jamroot.jam", """ + 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", """ + t.write("hello.cpp", "int main() {}") + 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() {}") t.run_build_system(t.adjust_suffix("hello.obj")) t.expect_output_line("*depends on itself*", False) diff --git a/v2/test/build_no.py b/v2/test/build_no.py index ce5c51e46..f6e6f9305 100644 --- a/v2/test/build_no.py +++ b/v2/test/build_no.py @@ -1,28 +1,22 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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 no property prevents a target from being built. -from BoostBuild import Tester, List -import string +# Tests that no property prevents a target from being built. +import BoostBuild -# Create a temporary working directory -t = Tester() +t = BoostBuild.Tester() -# Create the needed files -t.write("Jamroot", """ +t.write("jamroot.jam", """ exe hello : hello.cpp : debug:no ; """) -t.write("hello.cpp", """ -int main() -{ - return 0; -} +t.write("hello.cpp", """ +int main() {} """) t.run_build_system() @@ -31,5 +25,4 @@ t.expect_nothing_more() t.run_build_system("release") t.expect_addition("bin/$toolset/release/hello.exe") - t.cleanup() diff --git a/v2/test/c_file.py b/v2/test/c_file.py index cf6121e9d..28fe25311 100644 --- a/v2/test/c_file.py +++ b/v2/test/c_file.py @@ -1,26 +1,27 @@ #!/usr/bin/python -# 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) +# 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) -# Test that C files are compiled by C compiler -from BoostBuild import Tester, List +# Test that C files are compiled by a C compiler. -t = Tester() +import BoostBuild -t.write("project-root.jam", "") -t.write("Jamfile", """ +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ project ; - exe hello : hello.cpp a.c ; """) + t.write("hello.cpp", """ extern "C" int foo(); int main() { return foo(); } """) + t.write("a.c", """ -// This won't compile unless in C mode +// This will not compile unless in C mode. int foo() { int new = 0; @@ -28,6 +29,7 @@ int foo() return new; } """) + t.run_build_system() t.expect_addition("bin/$toolset/debug/hello.exe") diff --git a/v2/test/chain.py b/v2/test/chain.py index b11979928..ddc6b7308 100644 --- a/v2/test/chain.py +++ b/v2/test/chain.py @@ -5,38 +5,33 @@ # 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 tests that -# 1) the 'make' correctly assigns types to produced targets -# 2) than if 'make' create targets of type CPP, they are -# correctly used (there was a bug with it). +# This tests that : +# 1) the 'make' correctly assigns types to produced targets +# 2) if 'make' creates targets of type CPP, they are correctly used. -from BoostBuild import Tester -t = Tester() +import BoostBuild -# In order to correctly link this app, 'b.cpp', created by 'make' -# rule, should be compiled. -t.write("project-root.jam", "import gcc ;") -t.write("Jamfile", r''' -rule create ( dst : src * : properties * ) -{ - # hack to echo a space under NT - setup on $(dst) = "set x=int main(){ return 0; }" ; -} +t = BoostBuild.Tester() +# In order to correctly link this app, 'b.cpp', created by a 'make' rule, should +# be compiled. + +t.write("jamroot.jam", "import gcc ;") + +t.write("jamfile.jam", r''' import modules ; if [ modules.peek : NT ] { actions create { - $(setup) - echo %x% > $(<) + echo int main() {} > $(<) } } else { actions create { - echo "int main(){ return 0; }" > $(<) + echo "int main() {}" > $(<) } } @@ -44,13 +39,14 @@ IMPORT $(__name__) : create : : create ; exe a : l dummy.cpp ; -# needs to be static lib for Windows - main cannot appear in DLL +# Needs to be static lib for Windows - main() cannot appear in DLL. static-lib l : a.cpp b.cpp ; make b.cpp : : create ; - ''') + t.write("a.cpp", "") + t.write("dummy.cpp", "// msvc needs at least one object file\n") t.run_build_system() diff --git a/v2/test/clean.py b/v2/test/clean.py index 043f53597..8c95e6127 100644 --- a/v2/test/clean.py +++ b/v2/test/clean.py @@ -5,21 +5,19 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -from BoostBuild import Tester, List -import string +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("a.cpp", """ +t.write("a.cpp", """ int main() {} - """) -t.write("Jamroot", """ -exe a : a.cpp sub1//sub1 sub2//sub2 sub3//sub3 ; +t.write("jamroot.jam", """ +exe a : a.cpp sub1//sub1 sub2//sub2 sub3//sub3 ; """) -t.write("sub1/Jamfile", """ +t.write("sub1/jamfile.jam", """ lib sub1 : sub1.cpp sub1_2 ../sub2//sub2 ; lib sub1_2 : sub1_2.cpp ; """) @@ -29,7 +27,6 @@ t.write("sub1/sub1.cpp", """ __declspec(dllexport) #endif void sub1() {} - """) t.write("sub1/sub1_2.cpp", """ @@ -37,12 +34,10 @@ t.write("sub1/sub1_2.cpp", """ __declspec(dllexport) #endif void sub1() {} - """) - -t.write("sub2/Jamfile", """ -lib sub2 : sub2.cpp ; +t.write("sub2/jamfile.jam", """ +lib sub2 : sub2.cpp ; """) t.write("sub2/sub2.cpp", """ @@ -50,11 +45,10 @@ t.write("sub2/sub2.cpp", """ __declspec(dllexport) #endif void sub2() {} - """) -t.write("sub3/Jamroot", """ -lib sub3 : sub3.cpp ; +t.write("sub3/jamroot.jam", """ +lib sub3 : sub3.cpp ; """) t.write("sub3/sub3.cpp", """ @@ -62,11 +56,9 @@ t.write("sub3/sub3.cpp", """ __declspec(dllexport) #endif void sub3() {} - """) - -# The 'clean' should not remove files under separate Jamroot. +# The 'clean' should not remove files under separate jamroot.jam. t.run_build_system() t.run_build_system("--clean") t.expect_removal("bin/$toolset/debug/a.obj") @@ -77,15 +69,14 @@ t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") # The 'clean-all' removes everything it can reach. t.run_build_system() -t.run_build_system("--clean") +t.run_build_system("--clean-all") t.expect_removal("bin/$toolset/debug/a.obj") t.expect_removal("sub1/bin/$toolset/debug/sub1.obj") t.expect_removal("sub1/bin/$toolset/debug/sub1_2.obj") t.expect_removal("sub2/bin/$toolset/debug/sub2.obj") t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") -# The 'clean' together with project target removes -# only under that probject +# The 'clean' together with project target removes only under that project. t.run_build_system() t.run_build_system("sub1 --clean") t.expect_nothing("bin/$toolset/debug/a.obj") @@ -94,7 +85,7 @@ t.expect_removal("sub1/bin/$toolset/debug/sub1_2.obj") t.expect_nothing("sub2/bin/$toolset/debug/sub2.obj") t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") -# And clean-all removes everything. +# And 'clean-all' removes everything. t.run_build_system() t.run_build_system("sub1 --clean-all") t.expect_nothing("bin/$toolset/debug/a.obj") @@ -103,9 +94,8 @@ t.expect_removal("sub1/bin/$toolset/debug/sub1_2.obj") t.expect_removal("sub2/bin/$toolset/debug/sub2.obj") t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") -# If main target is explicitly named, we should not remove -# files from other targets. - +# If main target is explicitly named, we should not remove files from other +# targets. t.run_build_system() t.run_build_system("sub1//sub1 --clean") t.expect_removal("sub1/bin/$toolset/debug/sub1.obj") @@ -113,18 +103,14 @@ t.expect_nothing("sub1/bin/$toolset/debug/sub1_2.obj") t.expect_nothing("sub2/bin/$toolset/debug/sub2.obj") t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") - -# Regression test: sources of the 'cast' rule were mistakenly -# deleted. +# Regression test: sources of the 'cast' rule were mistakenly deleted. t.rm(".") -t.write("Jamroot", """ +t.write("jamroot.jam", """ import cast ; cast a cpp : a.h ; """) t.write("a.h", "") - t.run_build_system("--clean") t.expect_nothing("a.h") t.cleanup() - diff --git a/v2/test/composite.py b/v2/test/composite.py index d1a795be7..ca3fb3272 100644 --- a/v2/test/composite.py +++ b/v2/test/composite.py @@ -4,26 +4,22 @@ # 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) -# Test that composite properties are handled correctly. -from BoostBuild import Tester, List +# Test that composite properties are handled correctly. -t = Tester() +import BoostBuild -t.write("project-root.jam", "") -t.write("Jamfile", """ +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ exe hello : hello.cpp : release ; """) -t.write("hello.cpp", """ -int main() -{ - return 0; -} +t.write("hello.cpp", """ +int main() {} """) t.run_build_system() t.expect_addition("bin/$toolset/release/hello.exe") - t.cleanup() diff --git a/v2/test/conditionals.py b/v2/test/conditionals.py index 35651be73..b1d78a540 100644 --- a/v2/test/conditionals.py +++ b/v2/test/conditionals.py @@ -15,18 +15,18 @@ t = BoostBuild.Tester() # define. t.write("a.cpp", """ #ifdef STATIC -int main() { return 0; } +int main() {} #endif """) # Test conditionals in target requirements. -t.write("Jamroot.jam", "exe a : a.cpp : static:STATIC ;") +t.write("jamroot.jam", "exe a : a.cpp : static:STATIC ;") t.run_build_system("link=static") t.expect_addition("bin/$toolset/debug/link-static/a.exe") t.rm("bin") # Test conditionals in project requirements. -t.write("Jamroot.jam", """ +t.write("jamroot.jam", """ project : requirements static:STATIC ; exe a : a.cpp ; """) @@ -36,7 +36,7 @@ t.rm("bin") # Regression test for a bug found by Ali Azarbayejani. Conditionals inside usage # requirement were not being evaluated. -t.write("Jamroot.jam", """ +t.write("jamroot.jam", """ lib l : l.cpp : : : static:STATIC ; exe a : a.cpp l ; """) diff --git a/v2/test/conditionals2.py b/v2/test/conditionals2.py index 59e62a9aa..585e5ca77 100644 --- a/v2/test/conditionals2.py +++ b/v2/test/conditionals2.py @@ -4,9 +4,9 @@ # 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) -# Regression test: it was possible that due to evaluation of conditional -# requirements, two different values of non-free features were present in -# property set. +# Regression test: it was possible that due to evaluation of conditional +# requirements, two different values of non-free features were present in a +# property set. import BoostBuild @@ -14,7 +14,7 @@ t = BoostBuild.Tester() t.write("a.cpp", "") -t.write("Jamroot.jam", """ +t.write("jamroot.jam", """ import feature ; import common ; diff --git a/v2/test/conditionals3.py b/v2/test/conditionals3.py index 8144dd990..ca328ff1b 100644 --- a/v2/test/conditionals3.py +++ b/v2/test/conditionals3.py @@ -4,23 +4,23 @@ # 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) -# Test that conditional properties work, even if property is free, and value -# includes a colon. +# Test that conditional properties work, even if property is free, and value +# includes a colon. import BoostBuild t = BoostBuild.Tester() -t.write("Jamroot.jam", """ +t.write("jamroot.jam", """ exe hello : hello.cpp : debug:CLASS=Foo::Bar ; """) + t.write("hello.cpp", """ namespace Foo { class Bar { } ; } int main() { CLASS c; c; // Disables the unused variable warning. - return 0; } """) diff --git a/v2/test/conditionals_multiple.py b/v2/test/conditionals_multiple.py index 976e32a31..20b6b47f7 100755 --- a/v2/test/conditionals_multiple.py +++ b/v2/test/conditionals_multiple.py @@ -21,7 +21,8 @@ def test_multiple_conditions(): """Basic tests for properties conditioned on multiple other properties. """ - t = BoostBuild.Tester("--ignore-regular-config toolset=testToolset", pass_toolset=False, use_test_config=False) + t = BoostBuild.Tester("--ignore-regular-config toolset=testToolset", + pass_toolset=False, use_test_config=False) t.write("testToolset.jam", """ import feature ; @@ -29,7 +30,7 @@ feature.extend toolset : testToolset ; rule init ( ) { } """) - t.write("Jamroot.jam", """ + t.write("jamroot.jam", """ import feature ; import notfile ; import toolset ; @@ -134,7 +135,7 @@ feature.subfeature toolset %(toolset)s : version : 0 1 ; rule init ( version ? ) { } """ % {"toolset": toolset}) - t.write("Jamroot.jam", """ + t.write("jamroot.jam", """ import feature ; import notfile ; import toolset ; diff --git a/v2/test/configuration.py b/v2/test/configuration.py index add5003b8..46adfd3c9 100755 --- a/v2/test/configuration.py +++ b/v2/test/configuration.py @@ -23,7 +23,8 @@ def test_user_configuration(): path handling is tested. """ - t = BoostBuild.Tester("--debug-configuration", pass_toolset=False, use_test_config=False) + t = BoostBuild.Tester("--debug-configuration", pass_toolset=False, + use_test_config=False) implicitConfigLoadMessage = "notice: Loading user-config configuration file: *" explicitConfigLoadMessage = "notice: Loading explicitly specified user configuration file:" @@ -46,7 +47,7 @@ import feature ; feature.extend toolset : %s ; rule init ( ) { } """ % toolsetName ) - t.write("Jamroot.jam", "using %s ;" % toolsetName) + t.write("jamroot.jam", "using %s ;" % toolsetName) t.run_build_system() t.expect_output_line(explicitConfigLoadMessage, False) diff --git a/v2/test/core_d12.py b/v2/test/core_d12.py index 94f3cdb33..83076350a 100644 --- a/v2/test/core_d12.py +++ b/v2/test/core_d12.py @@ -1,8 +1,8 @@ #!/usr/bin/python -# 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 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) # This tests correct handling of "-d1" and "-d2" options. @@ -11,14 +11,9 @@ import BoostBuild t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", """ -actions a { -} - -actions quietly b { -} - +actions a { } +actions quietly b { } ALWAYS all ; - a all ; b all ; """) diff --git a/v2/test/core_delete_module.py b/v2/test/core_delete_module.py index 6a5fa7c03..b02fd95a3 100644 --- a/v2/test/core_delete_module.py +++ b/v2/test/core_delete_module.py @@ -1,8 +1,8 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# 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 +# 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 tests the facilities for deleting modules. @@ -28,12 +28,12 @@ module foo { EXIT DELETE_MODULE failed to kill foo's variables ; } - + rule bar { } var = x y ; - + DELETE_MODULE foo ; - + if $(var) { EXIT internal DELETE_MODULE failed to kill foo's variables ; diff --git a/v2/test/core_dependencies.py b/v2/test/core_dependencies.py index ee6de2aba..2b2ef368d 100644 --- a/v2/test/core_dependencies.py +++ b/v2/test/core_dependencies.py @@ -4,11 +4,12 @@ # 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 tests correct handling of dependencies, specifically, on -# generated sources, and from generated sources. +# This tests correct handling of dependencies, specifically, on generated +# sources, and from generated sources. import BoostBuild -from string import find + +import string t = BoostBuild.Tester(pass_toolset=0) @@ -37,20 +38,22 @@ HDRRULE on b foo.h bar.h = hdrrule ; HDRSCAN on b foo.h bar.h = \"#include <(.*)>\" ; """ -# This creates 'a' which depends on 'b', which is generated. -# The generated 'b' contains '#include ' and no rules for -# foo.h are given. The system should error out on the first invocation. +# This creates 'a' which depends on 'b', which is generated. The generated 'b' +# contains '#include ' and no rules for foo.h are given. The system +# should error out on the first invocation. t.run_build_system("-f-", stdin=code) -t.fail_test(find(t.stdout(), "...skipped a for lack of foo.h...") == -1) +t.fail_test(string.find(t.stdout(), "...skipped a for lack of foo.h...") == -1) t.rm('b') -# Now test that if target 'c' also depends on 'b', then it won't be built, as well. + +# Now test that if target 'c' also depends on 'b', then it will not be built, as +# well. t.run_build_system("-f-", stdin=code + " copy c : b ; DEPENDS c : b ; DEPENDS all : c ; ") -t.fail_test(find(t.stdout(), "...skipped c for lack of foo.h...") == -1) +t.fail_test(string.find(t.stdout(), "...skipped c for lack of foo.h...") == -1) - -# Now add a rule for creating foo.h t.rm('b') + +# Now add a rule for creating foo.h. code += """ actions create-foo { @@ -60,36 +63,35 @@ create-foo foo.h ; """ t.run_build_system("-f-", stdin=code) -# Run two times, adding explicit dependency from all to foo.h at -# the beginning and at the end, to make sure that foo.h is generated before -# 'a' in all cases. +# Run two times, adding explicit dependency from all to foo.h at the beginning +# and at the end, to make sure that foo.h is generated before 'a' in all cases. -def mk_right_order_func(s1, s2): - def right_order(s): - n1 = find(s, s1) - n2 = find(s, s2) - return n1 != -1 and n2 != -1 and n1 < n2 - return right_order +def mk_correct_order_func(s1, s2): + def correct_order(s): + n1 = string.find(s, s1) + n2 = string.find(s, s2) + return ( n1 != -1 ) and ( n2 != -1 ) and ( n1 < n2 ) + return correct_order -right_order = mk_right_order_func("create-foo", "copy a") +correct_order = mk_correct_order_func("create-foo", "copy a") t.rm(["a", "b", "foo.h"]) t.run_build_system("-d+2 -f-", stdin=code + " DEPENDS all : foo.h ;") -t.fail_test(not right_order(t.stdout())) +t.fail_test(not correct_order(t.stdout())) t.rm(["a", "b", "foo.h"]) t.run_build_system("-d+2 -f-", stdin=" DEPENDS all : foo.h ; " + code) -t.fail_test(not right_order(t.stdout())) +t.fail_test(not correct_order(t.stdout())) -# Now foo.h exists. Test include from b -> foo.h -> bar.h -> biz.h -# b and foo.h already have updating actions. +# Now foo.h exists. Test include from b -> foo.h -> bar.h -> biz.h. b and foo.h +# already have updating actions. t.rm(["a", "b"]) t.write("foo.h", "#include ") t.write("bar.h", "#include ") t.run_build_system("-d+2 -f-", stdin=code) -t.fail_test(find(t.stdout(), "...skipped a for lack of biz.h...") == -1) +t.fail_test(string.find(t.stdout(), "...skipped a for lack of biz.h...") == -1) -# Add an action for biz.h +# Add an action for biz.h. code += """ actions create-biz { @@ -97,15 +99,15 @@ actions create-biz } create-biz biz.h ; """ + t.rm(["b"]) -right_order = mk_right_order_func("create-biz", "copy a") +correct_order = mk_correct_order_func("create-biz", "copy a") t.run_build_system("-d+2 -f-", stdin=code + " DEPENDS all : biz.h ;") -t.fail_test(not right_order(t.stdout())) +t.fail_test(not correct_order(t.stdout())) t.rm(["a", "biz.h"]) t.run_build_system("-d+2 -f-", stdin=" DEPENDS all : biz.h ; " + code) -t.fail_test(not right_order(t.stdout())) - +t.fail_test(not correct_order(t.stdout())) t.write("a", "") @@ -147,10 +149,9 @@ rule hdrrule INCLUDES $(1) : d ; } """ -right_order = mk_right_order_func("create-d", "copy main") + +correct_order = mk_correct_order_func("create-d", "copy main") t.run_build_system("-d2 -f-", stdin=code) -t.fail_test(not right_order(t.stdout())) - - +t.fail_test(not correct_order(t.stdout())) t.cleanup() diff --git a/v2/test/core_import_module.py b/v2/test/core_import_module.py index 0f1d6cea1..fab209e4c 100644 --- a/v2/test/core_import_module.py +++ b/v2/test/core_import_module.py @@ -1,24 +1,23 @@ #!/usr/bin/python -# 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) +# 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) -from BoostBuild import Tester, List +import BoostBuild - -t = Tester(pass_toolset=0) - -# Test that +t = BoostBuild.Tester(pass_toolset=0) t.write("code", """ -module a { +module a +{ rule r1 ( ) { ECHO R1 ; } } -module a2 { +module a2 +{ rule r2 ( ) { ECHO R2 ; @@ -26,9 +25,9 @@ module a2 { } IMPORT a2 : r2 : : a2.r2 ; -module b { +module b +{ IMPORT_MODULE a : b ; - rule test { # Call rule visible via IMPORT_MODULE @@ -41,19 +40,19 @@ module b { IMPORT b : test : : test ; test ; -module c { +module c +{ rule test { ECHO CTEST ; } -} +} IMPORT_MODULE c : ; c.test ; actions do-nothing { } do-nothing all ; - """) t.run_build_system("-fcode", stdout="""R1 diff --git a/v2/test/core_modifiers.py b/v2/test/core_modifiers.py index bebcc5fde..fb95cbfbd 100644 --- a/v2/test/core_modifiers.py +++ b/v2/test/core_modifiers.py @@ -1,18 +1,17 @@ #!/usr/bin/python -# 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) +# 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) # This tests the "existing" and "updated" modifiers on actions. import BoostBuild -from string import strip, replace +import string t = BoostBuild.Tester(pass_toolset=0) code = """ - DEPENDS all : a ; ALWAYS a ; NOTFILE a ; @@ -36,25 +35,17 @@ t.write("file.jam", code) t.write("a-1", "") t.run_build_system("-ffile.jam") -t.fail_test(strip(t.read("list")) != "a-1") +t.fail_test(string.strip(t.read("list")) != "a-1") t.rm(["a-3", "list"]) -code = replace(code, "existing", "updated") +code = string.replace(code, "existing", "updated") t.write("file.jam", code) t.run_build_system("-ffile.jam") -t.fail_test(strip(t.read("list")) != "a-3") +t.fail_test(string.strip(t.read("list")) != "a-3") -code = replace(code, "updated", "existing updated") +code = string.replace(code, "updated", "existing updated") t.write("file.jam", code) t.run_build_system("-ffile.jam") -t.fail_test(strip(t.read("list")) != "a-1 a-3") - - - - - - - - +t.fail_test(string.strip(t.read("list")) != "a-1 a-3") t.cleanup() diff --git a/v2/test/core_varnames.py b/v2/test/core_varnames.py index 8e48bb3b8..a94ed8fa5 100644 --- a/v2/test/core_varnames.py +++ b/v2/test/core_varnames.py @@ -1,10 +1,10 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# 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 +# 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 tests the core rule for enumerating the variable names in a module +# This tests the core rule for enumerating the variable names in a module. import BoostBuild @@ -34,4 +34,5 @@ NOTFILE xx ; """) t.run_build_system("-ffile.jam", status=0) + t.cleanup() diff --git a/v2/test/custom_generator.py b/v2/test/custom_generator.py index 7b73e2f22..a3395c7e8 100644 --- a/v2/test/custom_generator.py +++ b/v2/test/custom_generator.py @@ -4,19 +4,17 @@ # 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) +# Attempt to declare a generator for creating OBJ from RC files. That generator +# should be considered together with standard CPP->OBJ generators and +# successfully create the target. Since we do not have a RC compiler everywhere, +# we fake the action. The resulting OBJ will be unusable, but it must be +# created. -from BoostBuild import Tester, List +import BoostBuild +t = BoostBuild.Tester() -t = Tester() - -# Attempt to declare a generator for creating OBJ from RC files. -# That generator should be considered together with standard -# CPP->OBJ generators and successfully create the target. -# Since we don't have RC compiler everywhere, we fake the action. -# The resulting OBJ will be unusable, but it must be created. - -t.write("project-root.jam", """ +t.write("jamroot.jam", """ import rcc ; """) @@ -25,8 +23,8 @@ import type ; import generators ; import print ; -# Use 'RCC' to avoid conflicts with definitions in -# the standard rc.jam and msvc.jam +# Use 'RCC' to avoid conflicts with definitions in the standard rc.jam and +# msvc.jam type.register RCC : rcc ; rule resource-compile ( targets * : sources * : properties * ) @@ -36,10 +34,9 @@ rule resource-compile ( targets * : sources * : properties * ) } generators.register-standard rcc.resource-compile : RCC : OBJ ; - """) -t.write("Jamfile", """ +t.write("jamfile.jam", """ obj r : r.rcc ; """) @@ -50,6 +47,3 @@ t.run_build_system() t.expect_content("bin/$toolset/debug/r.obj", "rc-object") t.cleanup() - - - diff --git a/v2/test/default_build.py b/v2/test/default_build.py index 90a188aef..93d05ae3b 100644 --- a/v2/test/default_build.py +++ b/v2/test/default_build.py @@ -1,38 +1,38 @@ #!/usr/bin/python -# Copyright 2003 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 2003 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) # Test that default build clause actually has any effect. -from BoostBuild import Tester, List -t = Tester() +import BoostBuild -t.write("project-root.jam", "import gcc ;") -t.write("Jamfile", "exe a : a.cpp : : debug release ;") -t.write("a.cpp", "int main() { return 0; }\n") +t = BoostBuild.Tester() + +t.write("jamroot.jam", "import gcc ;") +t.write("jamfile.jam", "exe a : a.cpp : : debug release ;") +t.write("a.cpp", "int main() {}\n") t.run_build_system() t.expect_addition("bin/$toolset/debug/a.exe") t.expect_addition("bin/$toolset/release/a.exe") -# Check that explictly-specified build variant supresses -# default-build +# Check that explictly-specified build variant supresses default-build. t.rm("bin") t.run_build_system("release") -t.expect_addition(List("bin/$toolset/release/") * "a.exe a.obj") +t.expect_addition(BoostBuild.List("bin/$toolset/release/") * "a.exe a.obj") t.expect_nothing_more() -# Now check that we can specify explicit build request and -# default-build will be combined with it +# Now check that we can specify explicit build request and default-build will be +# combined with it. t.run_build_system("optimization=space") t.expect_addition("bin/$toolset/debug/optimization-space/a.exe") t.expect_addition("bin/$toolset/release/optimization-space/a.exe") # Test that default-build must be identical in all alternatives. Error case. -t.write("Jamfile", """ +t.write("jamfile.jam", """ exe a : a.cpp : : debug ; exe a : b.cpp : : ; """) @@ -44,40 +44,40 @@ differing from previous default build debug """ t.run_build_system("-n --no-error-backtrace", status=1, stdout=expected) -# Test that default-build must be identical in all alternatives. No Error case, empty default build. -t.write("Jamfile", """ +# Test that default-build must be identical in all alternatives. No Error case, +# empty default build. +t.write("jamfile.jam", """ exe a : a.cpp : debug ; exe a : b.cpp : release ; """) t.run_build_system("-n --no-error-backtrace", status=0) -# Now try a harder example: default build which contains -# should cause to be present when "b" is compiled. -# This happens only of "build-project b" is placed first. -t.write("Jamfile", """ - project - : default-build FOO - ; - - build-project a ; - build-project b ; +# Now try a harder example: default build which contains should cause +# to be present when "b" is compiled. This happens only if +# "build-project b" is placed first. +t.write("jamfile.jam", """ +project : default-build FOO ; +build-project a ; +build-project b ; """) -t.write("a/Jamfile", """ - exe a : a.cpp ../b//b ; +t.write("a/jamfile.jam", """ +exe a : a.cpp ../b//b ; """) + t.write("a/a.cpp", """ #ifdef _WIN32 __declspec(dllimport) #endif void foo(); -int main() { foo(); return 0; } +int main() { foo(); } """) -t.write("b/Jamfile", """ - lib b : b.cpp ; +t.write("b/jamfile.jam", """ +lib b : b.cpp ; """) + t.write("b/b.cpp", """ #ifdef FOO #ifdef _WIN32 diff --git a/v2/test/default_features.py b/v2/test/default_features.py index 2924d8dfc..4d810caa7 100644 --- a/v2/test/default_features.py +++ b/v2/test/default_features.py @@ -1,44 +1,39 @@ #!/usr/bin/python -# 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) +# 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) -# Test that features with default values are always present -# in build properties of any target. +# Test that features with default values are always present in build properties +# of any target. -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() # Declare *non-propagated* feature foo. -t.write("project-root.jam", """ +t.write("jamroot.jam", """ import feature : feature ; - feature foo : on off ; """) -# Note that 'on' won't be propagated -# to 'd/l'. -t.write("Jamfile", """ +# Note that 'on' will not be propagated to 'd/l'. +t.write("jamfile.jam", """ exe hello : hello.cpp d//l ; """) + t.write("hello.cpp", """ #ifdef _WIN32 __declspec(dllimport) #endif void foo(); -int main() -{ - foo(); - return 1; -} - +int main() { foo(); } """) -t.write("d/Jamfile", """ +t.write("d/jamfile.jam", """ lib l : l.cpp : on:FOO ; """) + t.write("d/l.cpp", """ #ifdef _WIN32 __declspec(dllexport) @@ -46,7 +41,6 @@ __declspec(dllexport) #ifdef FOO void foo() {} #endif - """) t.run_build_system() diff --git a/v2/test/default_toolset.py b/v2/test/default_toolset.py index fc8199f62..e430c68a7 100755 --- a/v2/test/default_toolset.py +++ b/v2/test/default_toolset.py @@ -58,7 +58,7 @@ rule init ( version ) { ECHO "%(message_initialized)s" ; } 'toolset_version_unused': toolset_version_unused}) # Main Boost Build project script. - t.write("Jamroot.jam", """ + t.write("jamroot.jam", """ import build-system ; import errors ; import feature ; @@ -121,7 +121,7 @@ def test_default_toolset_on_os( os, expected_toolset ): t = BoostBuild.Tester("--user-config= --ignore-site-config", pass_toolset=False, use_test_config=False) - t.write("Jamroot.jam", "modules.poke os : .name : %s ;" % os) + t.write("jamroot.jam", "modules.poke os : .name : %s ;" % os) # We need to tell the test system to ignore stderr output as attempting to # load missing toolsets might cause random failures with which we are not @@ -159,7 +159,7 @@ rule init ( ) { } """ % {'toolset_name': toolset_name}) # Main Boost Build project script. - t.write("Jamroot.jam", """ + t.write("jamroot.jam", """ import build-system ; import errors ; import feature ; diff --git a/v2/test/dependency-test/Jamfile b/v2/test/dependency-test/jamfile.jam similarity index 100% rename from v2/test/dependency-test/Jamfile rename to v2/test/dependency-test/jamfile.jam diff --git a/v2/test/dependency-test/project-root.jam b/v2/test/dependency-test/jamroot.jam similarity index 100% rename from v2/test/dependency-test/project-root.jam rename to v2/test/dependency-test/jamroot.jam diff --git a/v2/test/dependency_property.py b/v2/test/dependency_property.py index 5383108b2..2f19ba3f8 100644 --- a/v2/test/dependency_property.py +++ b/v2/test/dependency_property.py @@ -4,30 +4,25 @@ # 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) -# Regression test: virtual targets with different dependency properties -# were considered different by 'virtual-target.register', but the code -# which determined target paths ignored dependency properties --- so both -# targets used to be placed to the same location. +# Regression test: virtual targets with different dependency properties were +# considered different by 'virtual-target.register', but the code which +# determined target paths ignored dependency properties --- so both targets used +# to be placed to the same location. -from BoostBuild import Tester, List -from string import find +import BoostBuild +import string -t = Tester() +t = BoostBuild.Tester() -t.write("project-root.jam", "") -t.write("Jamfile", """ +t.write("jamroot.jam", """ lib foo : foo.cpp ; exe hello : hello.cpp ; exe hello2 : hello.cpp : foo ; """) -t.write("hello.cpp", """ -int main() -{ - return 0; -} -""") +t.write("hello.cpp", "int main() {}\n") + t.write("foo.cpp", """ #ifdef _WIN32 __declspec(dllexport) @@ -36,6 +31,6 @@ void foo() {} """) t.run_build_system("--no-error-backtrace", status=1) -t.fail_test(find(t.stdout(), "Duplicate name of actual target") == -1) +t.fail_test(string.find(t.stdout(), "Duplicate name of actual target") == -1) t.cleanup() diff --git a/v2/test/dependency_test.py b/v2/test/dependency_test.py index be056f415..7da20712a 100644 --- a/v2/test/dependency_test.py +++ b/v2/test/dependency_test.py @@ -5,19 +5,20 @@ # 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) -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() t.set_tree("dependency-test") + t.run_build_system() -# Check that main target 'c' was able to find 'x.h' from -# 'a's dependency graph + +# Check that main target 'c' was able to find 'x.h' from 'a's dependency graph. t.expect_addition("bin/$toolset/debug/c.exe") # Check handling of first level includes. -# Both 'a' and 'b' include "a.h" and should be updated +# Both 'a' and 'b' include "a.h" and should be updated. t.touch("a.h") t.run_build_system() @@ -26,14 +27,13 @@ t.expect_touch("bin/$toolset/debug/a.obj") t.expect_touch("bin/$toolset/debug/a_c.obj") t.expect_touch("bin/$toolset/debug/b.exe") t.expect_touch("bin/$toolset/debug/b.obj") -# Now, does not add dependency. -# It sound weird, but is intentional. Need -# to rename eventually. +# Now, does not add a dependency. It sound weird, but is +# intentional. Need to rename eventually. #t.expect_touch("bin/$toolset/debug/main-target-c/c.exe") t.ignore("*.tds") t.expect_nothing_more() -# Only 'a' include and should be updated +# Only 'a' include and should be updated. t.touch("src1/a.h") t.run_build_system() @@ -43,7 +43,7 @@ t.expect_touch("bin/$toolset/debug/a_c.obj") t.ignore("*.tds") t.expect_nothing_more() -# "src/a.h" includes "b.h" (in the same dir) +# "src/a.h" includes "b.h" (in the same dir). t.touch("src1/b.h") t.run_build_system() t.expect_touch("bin/$toolset/debug/a.exe") @@ -52,8 +52,8 @@ t.expect_touch("bin/$toolset/debug/a_c.obj") t.ignore("*.tds") t.expect_nothing_more() -# included by "src/b.h". We had a bug: file included via "", -# like "b.h" is in this case was not scanned at all. +# Included by "src/b.h". We had a bug: file included via "", like "b.h" is in +# this case was not scanned at all. t.touch("src1/c.h") t.run_build_system() t.expect_touch("bin/$toolset/debug/a.exe") @@ -62,41 +62,38 @@ t.touch("b.h") t.run_build_system() t.expect_nothing_more() -# Test dependency on generated header. -# TODO: we have also to check that generated header is found correctly -# if it is different for different subvariants. Lacking any toolset -# support, this check will be implemented later. +# Test dependency on a generated header. +# +# TODO: we have also to check that generated header is found correctly if it is +# different for different subvariants. Lacking any toolset support, this check +# will be implemented later. t.touch("x.foo") t.run_build_system() t.expect_touch("bin/$toolset/debug/a.obj") t.expect_touch("bin/$toolset/debug/a_c.obj") -# Check that generated headers are scanned for dependencies as well +# Check that generated headers are scanned for dependencies as well. t.touch("src1/z.h") t.run_build_system() t.expect_touch("bin/$toolset/debug/a.obj") t.expect_touch("bin/$toolset/debug/a_c.obj") -# Regression test: on windows, with absolute paths -# were not considered when scanning dependencies. - +# Regression test: on Windows, with absolute paths were not +# considered when scanning dependencies. t.rm(".") -t.write("Jamroot", """ +t.write("jamroot.jam", """ path-constant TOP : . ; -exe app : main.cpp - : $(TOP)/include - ; +exe app : main.cpp : $(TOP)/include ; """); t.write("main.cpp", """ #include - -int main() { return 0; } - +int main() {} """) t.write("include/dir/header.h", "") + t.run_build_system() t.expect_addition("bin/$toolset/debug/main.obj") @@ -104,6 +101,4 @@ t.touch("include/dir/header.h") t.run_build_system() t.expect_touch("bin/$toolset/debug/main.obj") - - t.cleanup() diff --git a/v2/test/direct-request-test/Jamfile b/v2/test/direct-request-test/jamfile.jam similarity index 100% rename from v2/test/direct-request-test/Jamfile rename to v2/test/direct-request-test/jamfile.jam diff --git a/v2/test/direct-request-test/Jamfile2 b/v2/test/direct-request-test/jamfile2.jam similarity index 100% rename from v2/test/direct-request-test/Jamfile2 rename to v2/test/direct-request-test/jamfile2.jam diff --git a/v2/test/direct-request-test/project-root.jam b/v2/test/direct-request-test/jamroot.jam similarity index 100% rename from v2/test/direct-request-test/project-root.jam rename to v2/test/direct-request-test/jamroot.jam diff --git a/v2/test/direct_request_test.py b/v2/test/direct_request_test.py index 3b0880e83..000d15b64 100644 --- a/v2/test/direct_request_test.py +++ b/v2/test/direct_request_test.py @@ -1,46 +1,40 @@ #!/usr/bin/python -from BoostBuild import Tester, List -import os -from string import strip +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -# First check some startup + +# First check some startup. t.set_tree("direct-request-test") t.run_build_system(extra_args="define=MACROS") - t.expect_addition("bin/$toolset/debug/" - * (List("a.obj b.obj b.dll a.exe"))) + * (BoostBuild.List("a.obj b.obj b.dll a.exe"))) -# When building debug version, the 'define' still applies + +# When building a debug version, the 'define' still applies. t.rm("bin") t.run_build_system(extra_args="debug define=MACROS") t.expect_addition("bin/$toolset/debug/" - * (List("a.obj b.obj b.dll a.exe"))) + * (BoostBuild.List("a.obj b.obj b.dll a.exe"))) -# When building release version, the 'define' should not -# apply: we'll have direct build request 'release MACROS' -# and real build properties 'debug'. -t.copy("Jamfile2", "Jamfile") + +# When building release version, the 'define' should not apply: we will have +# direct build request 'release MACROS' and a real build property +# 'debug'. +t.copy("jamfile2.jam", "jamfile.jam") t.copy("b_inverse.cpp", "b.cpp") t.rm("bin") t.run_build_system(extra_args="release define=MACROS") -# Regression test: direct build request was not working -# when there's more than one level of 'build-project' - +# Regression test: direct build request was not working when there was more than +# one level of 'build-project'. t.rm(".") -t.write('project-root.jam', '') -t.write('Jamfile', 'build-project a ;') -t.write('a/Jamfile', 'build-project b ;') -t.write('a/b/Jamfile', '') - +t.write('jamroot.jam', '') +t.write('jamfile.jam', 'build-project a ;') +t.write('a/jamfile.jam', 'build-project b ;') +t.write('a/b/jamfile.jam', '') t.run_build_system("release") - - - - t.cleanup() diff --git a/v2/test/disambiguation.py b/v2/test/disambiguation.py index f74d2786b..91b14c5c1 100644 --- a/v2/test/disambiguation.py +++ b/v2/test/disambiguation.py @@ -1,30 +1,26 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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) -# Test that it's possible to add a suffix to a main target name to -# disambiguate that main target from another, and that this does not -# affect the names of the generated targets. -from BoostBuild import Tester, List +# Test that it is possible to add a suffix to a main target name to disambiguate +# that main target from another, and that this does not affect the names of the +# generated targets. -# Create a temporary working directory -t = Tester() +import BoostBuild -# Create the needed files -t.write("Jamroot", """ +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ exe hello.exe : hello.obj ; obj hello.obj : hello.cpp : debug ; obj hello.obj2 : hello.cpp : release ; """) -t.write("hello.cpp", """ -int main() -{ - return 0; -} +t.write("hello.cpp", """ +int main() {} """) t.run_build_system() @@ -33,5 +29,4 @@ t.expect_addition("bin/$toolset/debug/hello.exe") t.expect_addition("bin/$toolset/debug/hello.obj") t.expect_addition("bin/$toolset/release/hello.obj") - t.cleanup() diff --git a/v2/test/dll_path.py b/v2/test/dll_path.py index cdf640e20..4efc2019c 100644 --- a/v2/test/dll_path.py +++ b/v2/test/dll_path.py @@ -1,41 +1,38 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2003. 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) Vladimir Prus 2003. 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. -# Test that the property is correctly set when using -# true. -from BoostBuild import Tester, List -from string import find +# Test that the property is correctly set when using +# true. +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -# The point of this test is to have exe "main" which uses library "b", -# which uses library "a". When "main" is built with true, -# paths to both libraries should be present as values of feature. -# We create a special target type which reports values on its sources -# and compare the list of found values with out expectations. +# The point of this test is to have exe "main" which uses library "b", which +# uses library "a". When "main" is built with true, paths to +# both libraries should be present as values of feature. We create a +# special target type which reports values on its sources and compare +# the list of found values with out expectations. -t.write("Jamfile", """ +t.write("jamfile.jam", """ exe main : main.cpp b//b ; explicit main ; - -path-list mp : main ; +path-list mp : main ; """) -t.write("main.cpp", """ -int main() { return 0; } - +t.write("main.cpp", """ +int main() {} """) -t.write("project-root.jam", """ -using dll-paths ; +t.write("jamroot.jam", """ +using dll-paths ; """) -t.write("dll-paths.jam", """ +t.write("dll-paths.jam", """ import type ; import generators ; import feature ; @@ -43,18 +40,18 @@ import sequence ; import print ; import "class" : new ; -rule init ( ) -{ +rule init ( ) +{ type.register PATH_LIST : pathlist ; - - class dll-paths-list-generator : generator + + class dll-paths-list-generator : generator { rule __init__ ( ) { generator.__init__ dll-paths.list : EXE : PATH_LIST ; } - - rule generated-targets ( sources + : property-set : project name ? ) + + rule generated-targets ( sources + : property-set : project name ? ) { local dll-paths ; for local s in $(sources) @@ -64,15 +61,15 @@ rule init ( ) { local p = [ $(a).properties ] ; dll-paths += [ $(p).get ] ; - } + } } - return [ generator.generated-targets $(sources) - : [ $(property-set).add-raw $(dll-paths:G=) ] : $(project) $(name) ] ; - + return [ generator.generated-targets $(sources) : + [ $(property-set).add-raw $(dll-paths:G=) ] : + $(project) $(name) ] ; + } } generators.register [ new dll-paths-list-generator ] ; - } rule list ( target : sources * : properties * ) @@ -82,35 +79,30 @@ rule list ( target : sources * : properties * ) print.output $(target) ; print.text $(paths) ; } - """) -t.write("a/a.cpp", """ +t.write("a/a.cpp", """ void #if defined(_WIN32) __declspec(dllexport) #endif foo() {} - - """) -t.write("a/Jamfile", """ -lib a : a.cpp ; +t.write("a/jamfile.jam", """ +lib a : a.cpp ; """) -t.write("b/b.cpp", """ +t.write("b/b.cpp", """ void #if defined(_WIN32) __declspec(dllexport) #endif bar() {} - - """) -t.write("b/Jamfile", """ -lib b : b.cpp ../a//a ; +t.write("b/jamfile.jam", """ +lib b : b.cpp ../a//a ; """) t.run_build_system("hardcode-dll-paths=true") @@ -124,4 +116,3 @@ t.expect_content_line("bin/$toolset/debug/mp.pathlist", "*" + es1); t.expect_content_line("bin/$toolset/debug/mp.pathlist", "*" + es2); t.cleanup() - diff --git a/v2/test/double_loading.py b/v2/test/double_loading.py index 5286494ea..27004a176 100644 --- a/v2/test/double_loading.py +++ b/v2/test/double_loading.py @@ -4,15 +4,14 @@ # 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) -from BoostBuild import Tester, List -import string +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -# Regression test for double loading of the same Jamfile. -t.write("Jamfile.jam", "build-project subdir ;") -t.write("Jamroot.jam", "" ) -t.write("subdir/Jamfile.jam", 'ECHO "Loaded subdir" ;') +# Regression test for double loading of the same Jamfile. +t.write("jamroot.jam", "" ) +t.write("jamfile.jam", "build-project subdir ;") +t.write("subdir/jamfile.jam", 'ECHO "Loaded subdir" ;') t.run_build_system(subdir="subdir") t.expect_output_line("Loaded subdir") @@ -22,9 +21,9 @@ t.expect_output_line("Loaded subdir") # subdir via use-project, while subdir's Jamfile is being loaded. The motivation # why use-project referring to subprojects is useful can be found at # http://article.gmane.org/gmane.comp.lib.boost.build/3906/ -t.write("Jamfile.jam", "use-project /subdir : subdir ;") -t.write("Jamroot.jam", "" ) -t.write("subdir/Jamfile.jam", "project subdir ;") +t.write("jamroot.jam", "" ) +t.write("jamfile.jam", "use-project /subdir : subdir ;") +t.write("subdir/jamfile.jam", "project subdir ;") t.run_build_system(subdir="subdir"); diff --git a/v2/test/duplicate.py b/v2/test/duplicate.py index 18922e75b..1d0d5f7f2 100644 --- a/v2/test/duplicate.py +++ b/v2/test/duplicate.py @@ -4,40 +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) -# This test tries to stage the same file to the same location by *two* -# different stage rules, in two different projects. This is not exactly -# good thing to do, but still, V2 should handle this. We had two bugs: -# - since the file is referred from two projects, we created to different -# virtual targets -# - we also failed to figure out that the two target corresponding to the -# copied files (created in two projects) are actually equivivalent. +# This test tries to stage the same file to the same location by *two* different +# stage rules, in two different projects. This is not exactly good thing to do, +# but still, V2 should handle this. We had two bugs: +# - since the file is referred from two projects, we created to different +# virtual targets +# - we also failed to figure out that the two target corresponding to the copied +# files (created in two projects) are actually equivalent. -from BoostBuild import Tester, List +import BoostBuild +t = BoostBuild.Tester() -t = Tester() - -t.write("a.cpp", """ +t.write("a.cpp", """ """) -t.write("Jamfile", """ +t.write("jamroot.jam", """ build-project a ; -build-project b ; +build-project b ; """) -t.write("project-root.jam", """ +t.write("a/jamfile.jam", """ +stage bin : ../a.cpp : ../dist ; """) -t.write("a/Jamfile", """ -stage bin : ../a.cpp : ../dist ; -""") - -t.write("b/Jamfile", """ -stage bin : ../a.cpp : ../dist ; +t.write("b/jamfile.jam", """ +stage bin : ../a.cpp : ../dist ; """) t.run_build_system() t.expect_addition("dist/a.cpp") - t.cleanup() diff --git a/v2/test/example_customization.py b/v2/test/example_customization.py index fbb12071f..f8fe15cc2 100644 --- a/v2/test/example_customization.py +++ b/v2/test/example_customization.py @@ -1,15 +1,15 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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) -# Test the 'libraries' example. -from BoostBuild import Tester, List +# Test the 'customization' example. -# Create a temporary working directory -t = Tester() +import BoostBuild + +t = BoostBuild.Tester() t.set_tree("../example/customization") @@ -17,7 +17,5 @@ t.run_build_system() t.expect_addition(["bin/$toolset/debug/codegen.exe", "bin/$toolset/debug/usage.cpp"]) - - t.cleanup() diff --git a/v2/test/example_gettext.py b/v2/test/example_gettext.py index 3fcc4ec04..e7cfa8eb7 100644 --- a/v2/test/example_gettext.py +++ b/v2/test/example_gettext.py @@ -1,17 +1,17 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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) -# Test the 'libraries' example. -from BoostBuild import Tester, List +# Test the 'gettext' example. + +import BoostBuild import os import string -# Create a temporary working directory -t = Tester() +t = BoostBuild.Tester() t.set_tree("../example/gettext") @@ -20,7 +20,6 @@ t.run_build_system(stderr=None) t.expect_addition(["bin/$toolset/debug/main.exe", "bin/$toolset/debug/russian.mo"]) - file = t.adjust_names(["bin/$toolset/debug/main.exe"])[0] input_fd = os.popen(file) diff --git a/v2/test/example_libraries.py b/v2/test/example_libraries.py index 2d2d468e2..c40af74de 100644 --- a/v2/test/example_libraries.py +++ b/v2/test/example_libraries.py @@ -1,15 +1,15 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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) -# Test the 'libraries' example. -from BoostBuild import Tester, List +# Test the 'libraries' example. -# Create a temporary working directory -t = Tester() +import BoostBuild + +t = BoostBuild.Tester() t.set_tree("../example/libraries") @@ -18,5 +18,4 @@ t.run_build_system() t.expect_addition(["app/bin/$toolset/debug/app.exe", "util/foo/bin/$toolset/debug/bar.dll"]) - t.cleanup() diff --git a/v2/test/example_make.py b/v2/test/example_make.py index 3eb360912..1e62702ef 100644 --- a/v2/test/example_make.py +++ b/v2/test/example_make.py @@ -1,20 +1,20 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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) -# Test the 'libraries' example. -from BoostBuild import Tester, List +# Test the 'make' example. -# Create a temporary working directory -t = Tester() +import BoostBuild + +t = BoostBuild.Tester() t.set_tree("../example/make") t.run_build_system() -t.expect_addition(["bin/$toolset/debug/main.exe"]) - +t.expect_addition(["bin/$toolset/debug/main.cpp"]) + t.cleanup() diff --git a/v2/test/example_qt4.py b/v2/test/example_qt4.py index 37e364157..1b0dc27bd 100644 --- a/v2/test/example_qt4.py +++ b/v2/test/example_qt4.py @@ -6,10 +6,10 @@ # http://www.boost.org/LICENSE_1_0.txt) # Test the 'qt4' examples. -from BoostBuild import Tester, List -# Create a temporary working directory -t = Tester() +import BoostBuild + +t = BoostBuild.Tester() t.set_tree("../example/qt/qt4/hello") t.run_build_system() diff --git a/v2/test/expansion.py b/v2/test/expansion.py index b3e93e38c..a9f665356 100644 --- a/v2/test/expansion.py +++ b/v2/test/expansion.py @@ -4,88 +4,77 @@ # 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 template for Boost.Build tests. It creates a simple -# project that builds one exe from one source, and checks that the exe -# is really created. -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("a.cpp", """ +t.write("a.cpp", """ #ifdef CF_IS_OFF -int main() { return 0; } +int main() {} #endif - """) -t.write("b.cpp", """ +t.write("b.cpp", """ #ifdef CF_1 -int main() { return 0; } +int main() {} #endif - """) t.write("c.cpp", """ #ifdef FOO -int main() { return 0; } +int main() {} #endif - """) - -t.write("Jamfile", """ -# See if default value of composite feature 'cf' -# will be expanded to CF_IS_OFF +t.write("jamfile.jam", """ +# See if default value of composite feature 'cf' will be expanded to +# CF_IS_OFF. exe a : a.cpp ; # See if subfeature in requirements in expanded. exe b : b.cpp : on-1 ; # See if conditional requirements are recursively expanded. -exe c : c.cpp : $toolset:release release:FOO ; +exe c : c.cpp : $toolset:release release:FOO + ; """) -t.write("project-root.jam", """ +t.write("jamroot.jam", """ import feature ; - feature.feature cf : off on : composite incidental ; - feature.compose off : CF_IS_OFF ; - feature.subfeature cf on : version : 1 2 : composite optional incidental ; - feature.compose 1 : CF_1 ; - """) -t.expand_toolset("Jamfile") +t.expand_toolset("jamfile.jam") t.run_build_system() t.expect_addition(["bin/$toolset/debug/a.exe", "bin/$toolset/debug/b.exe", - "bin/$toolset/release/c.exe", - ]) + "bin/$toolset/release/c.exe"]) t.rm("bin") -# Test for issue BB60 + +# Test for issue BB60. + t.write("test.cpp", """ #include "header.h" -int main() { return 0; } +int main() {} """) -t.write("Jamfile", """ -project - : requirements $toolset:foo - ; + +t.write("jamfile.jam", """ +project : requirements $toolset:foo ; exe test : test.cpp : $toolset ; """) -t.expand_toolset("Jamfile") -t.write("foo/header.h", """ -""") -t.write("project-root.jam", "") + +t.expand_toolset("jamfile.jam") +t.write("foo/header.h", "\n") +t.write("jamroot.jam", "") + t.run_build_system() t.expect_addition("bin/$toolset/debug/test.exe") t.cleanup() - diff --git a/v2/test/explicit.py b/v2/test/explicit.py index a2c183308..2665becf8 100644 --- a/v2/test/explicit.py +++ b/v2/test/explicit.py @@ -4,32 +4,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 file is template for Boost.Build tests. It creates a simple -# project that builds one exe from one source, and checks that the exe -# is really created. -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("project-root.jam", "") -t.write("Jamfile", """ +t.write("jamroot.jam", "") +t.write("jamfile.jam", """ exe hello : hello.cpp ; exe hello2 : hello.cpp ; - explicit hello2 ; """) -t.write("hello.cpp", """ -int main() -{ - return 0; -} +t.write("hello.cpp", """ +int main() {} """) t.run_build_system() t.ignore("*.tds") -t.expect_addition(List("bin/$toolset/debug/hello") * [".exe", ".obj"]) +t.expect_addition(BoostBuild.List("bin/$toolset/debug/hello") * \ + [".exe", ".obj"]) t.expect_nothing_more() t.run_build_system("hello2") @@ -38,21 +32,21 @@ t.expect_addition("bin/$toolset/debug/hello2.exe") t.rm(".") -# Test that 'explicit' used in a helper rule applies to the current project, -# and not to the Jamfile where the helper rule is defined. -t.write("Jamroot", """ +# Test that 'explicit' used in a helper rule applies to the current project, and +# not to the Jamfile where the helper rule is defined. +t.write("jamroot.jam", """ rule myinstall ( name : target ) { install $(name)-bin : $(target) ; explicit $(name)-bin ; alias $(name) : $(name)-bin ; -} +} """) -t.write("sub/a.cpp", """ +t.write("sub/a.cpp", """ """) -t.write("sub/Jamfile", """ +t.write("sub/jamfile.jam", """ myinstall dist : a.cpp ; """) @@ -61,14 +55,12 @@ t.expect_addition("sub/dist-bin/a.cpp") t.rm("sub/dist-bin") -t.write("sub/Jamfile", """ +t.write("sub/jamfile.jam", """ myinstall dist : a.cpp ; explicit dist ; - """) t.run_build_system(subdir="sub") t.expect_nothing_more() - t.cleanup() diff --git a/v2/test/file_name_handling.py b/v2/test/file_name_handling.py index 3a797c33d..8e59e6821 100755 --- a/v2/test/file_name_handling.py +++ b/v2/test/file_name_handling.py @@ -33,10 +33,9 @@ import time # prepare_file() # -------------- # -# ################################################################################ -def prepare_file(tester, target_name, age_in_seconds = 0): +def prepare_file(tester, target_name, age_in_seconds=0): """Prepares a new file with the given name, optionally setting its last access and modification timestamps to the given number of seconds in the history. @@ -70,7 +69,7 @@ def test_simple_file_names(): t.write("testScript.jam", """ actions create-file { - echo Modified file content ($(1:E="")).> "$(1:E="")" + echo "Modified file content ($(1:E=""))."> "$(1:E="")" } DEPENDS all : standaloneTarget.txt ; diff --git a/v2/test/free_features_request.py b/v2/test/free_features_request.py index 61108be9c..108072758 100644 --- a/v2/test/free_features_request.py +++ b/v2/test/free_features_request.py @@ -1,29 +1,26 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2007. -# 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) +# Copyright (C) Vladimir Prus 2007. +# 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 a free feature specified on the command -# line applies to all targets ever built. -from BoostBuild import Tester, List +# Tests that a free feature specified on the command line applies to all targets +# ever built. +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("Jamroot", """ +t.write("jamroot.jam", """ exe hello : hello.cpp foo ; lib foo : foo.cpp ; """) + t.write("hello.cpp", """ extern void foo(); #ifdef FOO -int main() -{ - foo(); - return 0; -} +int main() { foo(); } #endif """) @@ -36,8 +33,8 @@ void foo() {} #endif """) -# If FOO is not defined when compiling the 'foo' -# target, we'll get a link error at this point. +# If FOO is not defined when compiling the 'foo' target, we will get a link +# error at this point. t.run_build_system("hello define=FOO") t.expect_addition("bin/$toolset/debug/hello.exe") diff --git a/v2/test/gcc_runtime.py b/v2/test/gcc_runtime.py index bb3bb75d2..a7e57550f 100644 --- a/v2/test/gcc_runtime.py +++ b/v2/test/gcc_runtime.py @@ -4,28 +4,28 @@ # 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) -# Tests that on gcc, we correctly report problem when static runtime -# is requested when building DLL. -from BoostBuild import Tester, List +# Tests that on gcc, we correctly report problem when static runtime is +# requested for building a shared library. + +import BoostBuild import string -t = Tester() +t = BoostBuild.Tester() -# Create the needed files -t.write("project-root.jam", "") -t.write("Jamfile", """ +# Create the needed files. +t.write("jamroot.jam", "") + +t.write("jamfile.jam", """ lib hello : hello.cpp ; """) + t.write("hello.cpp", """ -int main() -{ - return 0; -} +int main() { } """) t.run_build_system("runtime-link=static", status=1) t.fail_test(string.find(t.stdout(), - "On gcc, DLL can't be build with 'static'") == -1) + "On gcc, DLL can't be build with 'static'") == -1) t.run_build_system("link=static runtime-link=static") t.expect_addition("bin/$toolset/debug/link-static/runtime-link-static/hello.lib") diff --git a/v2/test/generator_selection.py b/v2/test/generator_selection.py new file mode 100755 index 000000000..c0500ea7a --- /dev/null +++ b/v2/test/generator_selection.py @@ -0,0 +1,110 @@ +#!/usr/bin/python + +# 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) + +# Tests that generators get selected correctly. + +import BoostBuild + + +################################################################################ +# +# test_generator_added_after_already_building_a_target_of_its_target_type() +# ------------------------------------------------------------------------- +# +################################################################################ + +def test_generator_added_after_already_building_a_target_of_its_target_type(): + """Regression test for a Boost Build bug causing it to not use a generator + if it got added after already building a targer of its target type. + """ + + t = BoostBuild.Tester() + + t.write("dummy.cpp", "void f() {}\n") + + t.write("jamroot.jam", """ +# Building this dummy target must not cause a later defined CPP target type +# generator not to be recognized as viable. +obj dummy : dummy.cpp ; +alias the-other-obj : Other//other-obj ; +""") + + t.write("Other/source.extension", "A dummy source file.") + + t.write("Other/mygen.jam", """ +import generators ; +import type ; +type.register MY_TYPE : extension ; +generators.register-standard mygen.generate-a-cpp-file : MY_TYPE : CPP ; +rule generate-a-cpp-file { ECHO Generating a CPP file... ; } +actions generate-a-cpp-file { echo void g() {} > "$(<)" } +""") + + t.write("Other/jamfile.jam", """ +import mygen ; +obj other-obj : source.extension ; +""") + + t.run_build_system() + t.expect_output_line("Generating a CPP file...") + t.expect_addition("bin/$toolset/debug/dummy.obj") + t.expect_addition("Other/bin/$toolset/debug/other-obj.obj") + + t.cleanup() + + +################################################################################ +# +# test_using_a_derived_source_type_created_after_generator_already_used() +# ----------------------------------------------------------------------- +# +################################################################################ + +def test_using_a_derived_source_type_created_after_generator_already_used(): + """Regression test for a Boost Build bug causing it to not use a generator + with a source type derived from one of the generator's sources but created + only after already using the generateor. + """ + + t = BoostBuild.Tester() + + t.write("dummy.cpp", "void f() {}\n") + + t.write("jamroot.jam", """ +# Building this dummy target must not cause a later defined UNGA_CPP target type +# not to be recognized as a viable source type for building OBJ targets. +obj dummy : dummy.cpp ; +alias the-test-output : Other//other-obj ; +""") + + t.write("Other/source.unga_cpp", "void g() {}\n") + + t.write("Other/jamfile.jam", """ +import type ; +type.register UNGA_CPP : unga_cpp : CPP ; +# We are careful not to do anything between defining our new UNGA_CPP target +# type and using the CPP --> OBJ generator that could potentially cover the +# Boost Build bug by clearing its internal viable source target type state. +obj other-obj : source.unga_cpp ; +""") + + t.run_build_system() + t.expect_addition("bin/$toolset/debug/dummy.obj") + t.expect_addition("Other/bin/$toolset/debug/other-obj.obj") + t.expect_nothing_more() + + t.cleanup() + + +################################################################################ +# +# main() +# ------ +# +################################################################################ + +test_generator_added_after_already_building_a_target_of_its_target_type() +test_using_a_derived_source_type_created_after_generator_already_used() diff --git a/v2/test/generators-test/Jamfile b/v2/test/generators-test/jamfile.jam similarity index 100% rename from v2/test/generators-test/Jamfile rename to v2/test/generators-test/jamfile.jam diff --git a/v2/test/generators-test/project-root.jam b/v2/test/generators-test/jamroot.jam similarity index 100% rename from v2/test/generators-test/project-root.jam rename to v2/test/generators-test/jamroot.jam diff --git a/v2/test/generators-test/lib/Jamfile b/v2/test/generators-test/lib/jamfile.jam similarity index 100% rename from v2/test/generators-test/lib/Jamfile rename to v2/test/generators-test/lib/jamfile.jam diff --git a/v2/test/generators_test.py b/v2/test/generators_test.py index 209960845..549a8e0ac 100644 --- a/v2/test/generators_test.py +++ b/v2/test/generators_test.py @@ -1,41 +1,30 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# Copyright 2002, 2003, 2005 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, 2005 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) -from BoostBuild import Tester, List -import os +import BoostBuild -t = Tester() +t = BoostBuild.Tester() t.set_tree("generators-test") + t.run_build_system() -t.expect_addition( - "bin/$toolset/debug/" - * ( - List( - "a.obj b.obj c.h c.cpp c.obj d_parser.whl d_lexer.dlp d_parser.cpp d_lexer.cpp " - + "d_parser.lr0 d_parser.h d_parser_symbols.h x.c x.obj y.x1 y.x2 " - + "y.cpp y.obj e.marked_cpp e.positions e.target_cpp e.obj ")) - ) -ok = 0 - +t.expect_addition( "bin/$toolset/debug/" * BoostBuild.List( "a.obj b.obj c.h " + + "c.cpp c.obj d_parser.whl d_lexer.dlp d_parser.cpp d_lexer.cpp " + + "d_parser.lr0 d_parser.h d_parser_symbols.h x.c x.obj y.x1 y.x2 y.cpp " + + "y.obj e.marked_cpp e.positions e.target_cpp e.obj")) t.expect_addition("bin/$toolset/debug/a.exe") - t.expect_addition(["lib/bin/$toolset/debug/c.obj", - "lib/bin/$toolset/debug/auxilliary.lib", - ]) - + "lib/bin/$toolset/debug/auxilliary.lib"]) t.run_build_system(subdir='lib') - t.expect_addition(["lib/bin/$toolset/debug/auxilliary2.dll"]) t.run_build_system(subdir='lib', extra_args="link=static") - t.expect_addition(["lib/bin/$toolset/debug/link-static/auxilliary2.lib"]) t.cleanup() diff --git a/v2/test/implicit_dependency.py b/v2/test/implicit_dependency.py index 5fecdd23a..4fc103ac6 100644 --- a/v2/test/implicit_dependency.py +++ b/v2/test/implicit_dependency.py @@ -1,20 +1,18 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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) -# Test the is respected even if the -# target referred-to is not build itself, but only referred -# to by . +# Test the is respected even if the target referred to is +# not built itself, but only referred to by . -from BoostBuild import Tester, List -import string +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("Jamroot", """ +t.write("jamroot.jam", """ make a.h : : gen-header ; explicit a.h ; @@ -37,20 +35,14 @@ else } """) -t.write("hello.cpp", """ +t.write("hello.cpp", """ #include "a.h" - -int main() -{ - return i; -} +int main() { return i; } """) - t.run_build_system() t.expect_addition("bin/$toolset/debug/hello.exe") t.cleanup() - diff --git a/v2/test/indirect_conditional.py b/v2/test/indirect_conditional.py index b877e37cc..6e9c18141 100644 --- a/v2/test/indirect_conditional.py +++ b/v2/test/indirect_conditional.py @@ -1,16 +1,15 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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) -from BoostBuild import Tester, List -import string +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("Jamroot", """ +t.write("jamroot.jam", """ exe a1 : a1.cpp : @a1-rule ; rule a1-rule ( properties * ) @@ -21,7 +20,8 @@ rule a1-rule ( properties * ) } } -exe a2 : a2.cpp : @$(__name__).a2-rule debug:speed ; +exe a2 : a2.cpp : @$(__name__).a2-rule + debug:speed ; rule a2-rule ( properties * ) { @@ -31,7 +31,8 @@ rule a2-rule ( properties * ) } } -exe a3 : a3.cpp : @$(__name__).a3-rule-1 @$(__name__).a3-rule-2 ; +exe a3 : a3.cpp : @$(__name__).a3-rule-1 + @$(__name__).a3-rule-2 ; rule a3-rule-1 ( properties * ) { @@ -48,32 +49,26 @@ rule a3-rule-2 ( properties * ) return speed ; } } - """) -t.write("a1.cpp", """ +t.write("a1.cpp", """ #ifdef OK int main() {} #endif - """) -t.write("a2.cpp", """ +t.write("a2.cpp", """ #ifdef OK int main() {} #endif - """) -t.write("a3.cpp", """ +t.write("a3.cpp", """ #ifdef OK int main() {} #endif - """) - - t.run_build_system() t.expect_addition("bin/$toolset/debug/a1.exe") @@ -81,4 +76,3 @@ t.expect_addition("bin/$toolset/debug/optimization-speed/a2.exe") t.expect_addition("bin/$toolset/debug/optimization-speed/a3.exe") t.cleanup() - diff --git a/v2/test/inherit_toolset.py b/v2/test/inherit_toolset.py index dfb4e1a26..ca050d2c4 100644 --- a/v2/test/inherit_toolset.py +++ b/v2/test/inherit_toolset.py @@ -1,76 +1,59 @@ #!/usr/bin/python -# 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) +# 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) -from BoostBuild import Tester, List -from string import find +import BoostBuild +import string -t = Tester(pass_toolset=0) +t = BoostBuild.Tester(pass_toolset=0) -t.write("a.cpp", """ +t.write("a.cpp", """ """) -t.write("yfc1.jam", """ -import feature : extend ; -import generators : register-standard ; +t.write("yfc1.jam", """ +import feature ; +import generators ; feature.extend toolset : yfc1 ; - -rule init ( ) -{ -} +rule init ( ) { } generators.register-standard yfc1.compile : CPP : OBJ : yfc1 ; generators.register-standard yfc1.link : OBJ : EXE : yfc1 ; -actions compile -{ - yfc1-compile -} - -actions link -{ - yfc1-link -} +actions compile { yfc1-compile } +actions link { yfc1-link } """) -t.write("yfc2.jam", """ -import feature : extend ; -import toolset : inherit ; +t.write("yfc2.jam", """ +import feature ; +import toolset ; feature.extend toolset : yfc2 ; toolset.inherit yfc2 : yfc1 ; +rule init ( ) { } -rule init ( ) -{ -} - -actions link -{ - yfc2-link -} +actions link { yfc2-link } """) -t.write("Jamfile", """ -exe a : a.cpp ; +t.write("jamfile.jam", """ +exe a : a.cpp ; """) -t.write("project-root.jam", """ +t.write("jamroot.jam", """ using yfc1 ; """) t.run_build_system("-n -d2 yfc1") -t.fail_test(find(t.stdout(), "yfc1-link") == -1) +t.fail_test(string.find(t.stdout(), "yfc1-link") == -1) -# Make sure we don't have to explicit 'use' yfc1. -t.write("project-root.jam", """ +# Make sure we do not have to explicitly 'use' yfc1. +t.write("jamroot.jam", """ using yfc2 ; """) t.run_build_system("-n -d2 yfc2") -t.fail_test(find(t.stdout(), "yfc2-link") == -1) +t.fail_test(string.find(t.stdout(), "yfc2-link") == -1) t.cleanup() - diff --git a/v2/test/inherited_dependency.py b/v2/test/inherited_dependency.py new file mode 100755 index 000000000..7d4895e07 --- /dev/null +++ b/v2/test/inherited_dependency.py @@ -0,0 +1,237 @@ +#!/usr/bin/python +# +# Copyright (c) 2008 Steven Watanabe +# +# 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) + +import BoostBuild + +tester = BoostBuild.Tester() + + +################################################################################ +# +# Test without giving the project an explicit id. +# +################################################################################ + +tester.write("jamroot.jam", """ +lib test : test.cpp ; +project : requirements test ; +build-project a ; +""") + +tester.write("test.cpp", """ +#ifdef _WIN32 + __declspec(dllexport) +#endif +void foo() {} +""") + +tester.write("a/test1.cpp", """ +int main() {} +""") + +tester.write("a/jamfile.jam", """ +exe test1 : test1.cpp ; +""") + +tester.run_build_system() + +tester.expect_addition("bin/$toolset/debug/test.obj") +tester.expect_addition("a/bin/$toolset/debug/test1.exe") + +tester.rm("bin") +tester.rm("a/bin") + + +################################################################################ +# +# Run the same test from the "a" directory. +# +################################################################################ + +tester.run_build_system(subdir="a") + +tester.expect_addition("bin/$toolset/debug/test.obj") +tester.expect_addition("a/bin/$toolset/debug/test1.exe") + +tester.rm("bin") +tester.rm("a/bin") + + +################################################################################ +# +# This time, do give the project an id. +# +################################################################################ + +tester.write("jamroot.jam", """ +lib test : test.cpp ; +project test_project : requirements test ; +build-project a ; +""") + +tester.run_build_system() + +tester.expect_addition("bin/$toolset/debug/test.obj") +tester.expect_addition("a/bin/$toolset/debug/test1.exe") + +tester.rm("bin") +tester.rm("a/bin") + + +################################################################################ +# +# Now, give the project an id in its attributes. +# +################################################################################ + +tester.write("jamroot.jam", """ +lib test : test.cpp ; +project : id test_project : requirements test ; +build-project a ; +""") + +tester.run_build_system() + +tester.expect_addition("bin/$toolset/debug/test.obj") +tester.expect_addition("a/bin/$toolset/debug/test1.exe") + +tester.rm("bin") +tester.rm("a/bin") + + +################################################################################ +# +# Give the project an id in both ways at once. +# +################################################################################ + +tester.write("jamroot.jam", """ +lib test : test.cpp ; +project test_project1 : id test_project : requirements test ; +build-project a ; +""") + +tester.run_build_system() + +tester.expect_addition("bin/$toolset/debug/test.obj") +tester.expect_addition("a/bin/$toolset/debug/test1.exe") + +tester.rm("bin") +tester.rm("a/bin") + + +################################################################################ +# +# Test an absolute path in native format. +# +################################################################################ + +tester.write("jamroot.jam", """ +import path ; +path-constant here : . ; +current-location = [ path.native [ path.root [ path.make $(here) ] [ path.pwd ] + ] ] ; +project test : requirements $(current-location)/a/test1.cpp ; +exe test : test.cpp ; +""") + +tester.run_build_system() +tester.expect_addition("bin/$toolset/debug/test.exe") + +tester.rm("bin") +tester.rm("a/bin") + + +################################################################################ +# +# Test an absolute path in canonical format. +# +################################################################################ + +tester.write("jamroot.jam", """ +import path ; +path-constant here : . ; +current-location = [ path.root [ path.make $(here) ] [ path.pwd ] ] ; +project test : requirements $(current-location)/a/test1.cpp ; +exe test : test.cpp ; +""") + +tester.run_build_system() +tester.expect_addition("bin/$toolset/debug/test.exe") + +tester.rm("bin") +tester.rm("a/bin") + + +################################################################################ +# +# Test dependency properties (e.g. ) whose targets are specified using a +# relative path. +# +################################################################################ + +# Use jamroot.jam rather than jamfile.jam to avoid inheriting the from +# the parent as that would would make test3 a source of itself. +tester.write("b/jamroot.jam", """ +obj test3 : test3.cpp ; +""") + +tester.write("b/test3.cpp", """ +void bar() {} +""") + +tester.write("jamroot.jam", """ +project test : requirements b//test3 ; +build-project a ; +""") + +tester.write("a/jamfile.jam", """ +exe test : test1.cpp ; +""") + +tester.write("a/test1.cpp", """ +void bar(); +int main() { bar(); } +""") + +tester.run_build_system() +tester.expect_addition("b/bin/$toolset/debug/test3.obj") +tester.expect_addition("a/bin/$toolset/debug/test.exe") + +tester.rm("bin") +tester.rm("a") +tester.rm("jamroot.jam") +tester.rm("test.cpp") + + +################################################################################ +# +# Test that source-location is respected. +# +################################################################################ + +tester.write("build/jamroot.jam", """ +project : requirements test.cpp : source-location ../src ; +""") + +tester.write("src/test.cpp", """ +int main() {} +""") + +tester.write("build/a/jamfile.jam", """ +project : source-location ../../a_src ; +exe test : test1.cpp ; +""") + +tester.write("a_src/test1.cpp", """ +""") + +tester.run_build_system(subdir="build/a") +tester.expect_addition("build/a/bin/$toolset/debug/test.exe") + +tester.cleanup() diff --git a/v2/test/inline.py b/v2/test/inline.py index 39bfecd75..df6c09892 100644 --- a/v2/test/inline.py +++ b/v2/test/inline.py @@ -1,31 +1,25 @@ #!/usr/bin/python -# Copyright 2003, 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, 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) -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("Jamroot", """ +t.write("jamroot.jam", """ project : requirements static ; -exe a : a.cpp [ lib helper : helper.cpp ] ; +exe a : a.cpp [ lib helper : helper.cpp ] ; """) t.write("a.cpp", """ extern void helper(); -int main() -{ - return 0; -} - +int main() {} """) t.write("helper.cpp", """ -void helper() -{ -} +void helper() {} """) t.run_build_system() @@ -37,13 +31,13 @@ t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib") t.rm("bin") -# Now check that inline targets with the same name but -# present in different places are not confused between -# each other, and with top-level targets. -t.write("Jamroot", """ + +# Now check that inline targets with the same name but present in different +# places are not confused between each other, and with top-level targets. +t.write("jamroot.jam", """ project : requirements static ; exe a : a.cpp [ lib helper : helper.cpp ] ; -exe a2 : a.cpp [ lib helper : helper.cpp ] ; +exe a2 : a.cpp [ lib helper : helper.cpp ] ; """) t.run_build_system() @@ -51,9 +45,10 @@ t.expect_addition("bin/$toolset/debug/link-static/a.exe") t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib") t.expect_addition("bin/$toolset/debug/link-static/a2__helper.lib") -# Check that the 'alias' target does not change name of -# inline targets, and that inline targets are explicit. -t.write("Jamroot", """ + +# Check that the 'alias' target does not change the name of inline targets, and +# that inline targets are explicit. +t.write("jamroot.jam", """ project : requirements static ; alias a : [ lib helper : helper.cpp ] ; explicit a ; @@ -67,4 +62,3 @@ t.run_build_system("a") t.expect_addition("bin/$toolset/debug/link-static/helper.lib") t.cleanup() - diff --git a/v2/test/Jamfile b/v2/test/jamfile.jam similarity index 100% rename from v2/test/Jamfile rename to v2/test/jamfile.jam diff --git a/v2/test/lib_source_property.py b/v2/test/lib_source_property.py index 34568a4b1..2290c1fbf 100644 --- a/v2/test/lib_source_property.py +++ b/v2/test/lib_source_property.py @@ -1,28 +1,27 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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) -# Regression test: if a library had no explicit sources, but -# only properties, it was built as it it were searched -# library, and the specified sources were not compiled. -from BoostBuild import Tester, List +# Regression test: if a library had no explicit sources, but only +# properties, it was built as if it were a searched library, and the specified +# sources were not compiled. -# Create a temporary working directory -t = Tester() +import BoostBuild -# Create the needed files -t.write("Jamroot", """ +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ lib a : : a.cpp ; """) + t.write("a.cpp", """ #ifdef _WIN32 __declspec(dllexport) #endif void foo() {} - """) t.run_build_system() @@ -30,8 +29,9 @@ t.expect_addition("bin/$toolset/debug/a.obj") t.rm("bin") -# Now try with -t.write("Jamroot", """ + +# Now try with . +t.write("jamroot.jam", """ rule test ( properties * ) { return a.cpp ; diff --git a/v2/test/library_chain.py b/v2/test/library_chain.py index f8ecb84be..6df744727 100644 --- a/v2/test/library_chain.py +++ b/v2/test/library_chain.py @@ -1,34 +1,31 @@ #!/usr/bin/python -# Copyright 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, 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) -# Test that a chain of libraries work ok, not matter if we use static or -# shared linking. -from BoostBuild import Tester, List, get_toolset +# Test that a chain of libraries works ok, no matter if we use static or shared +# linking. + +import BoostBuild import string import os -t = Tester() +t = BoostBuild.Tester() -t.write("Jamfile", """ -# Stage the binary, so that it will be relinked -# without hardcode-dll-paths. That will chech that -# we pass correct -rpath-link, even if not passing -# -rpath. +t.write("jamfile.jam", """ +# Stage the binary, so that it will be relinked without hardcode-dll-paths. That +# will chech that we pass correct -rpath-link, even if not passing -rpath. stage dist : main ; -exe main : main.cpp b ; +exe main : main.cpp b ; """) -t.write("main.cpp", """ +t.write("main.cpp", """ void foo(); - -int main() { foo(); return 0; } - +int main() { foo(); } """) -t.write("project-root.jam", """ +t.write("jamroot.jam", """ """) t.write("a/a.cpp", """ @@ -41,26 +38,24 @@ void #if defined(_WIN32) __declspec(dllexport) #endif -geek() {} +geek() {} """) -t.write("a/Jamfile", """ -lib a : a.cpp ; +t.write("a/jamfile.jam", """ +lib a : a.cpp ; """) -t.write("b/b.cpp", """ +t.write("b/b.cpp", """ void geek(); - -void +void #if defined(_WIN32) __declspec(dllexport) #endif foo() { geek(); } - """) -t.write("b/Jamfile", """ -lib b : b.cpp ../a//a ; +t.write("b/jamfile.jam", """ +lib b : b.cpp ../a//a ; """) t.run_build_system(stderr=None) @@ -71,84 +66,92 @@ t.run_build_system("link=static") t.expect_addition("bin/$toolset/debug/link-static/main.exe") t.rm(["bin", "a/bin", "b/bin"]) -# Check that works for static linking. -t.write("b/Jamfile", """ -lib b : b.cpp : ../a//a ; +# Check that works for static linking. +t.write("b/jamfile.jam", """ +lib b : b.cpp : ../a//a ; """) + t.run_build_system("link=static") t.expect_addition("bin/$toolset/debug/link-static/main.exe") t.rm(["bin", "a/bin", "b/bin"]) -t.write("b/Jamfile", """ -lib b : b.cpp ../a//a/shared : static ; + +t.write("b/jamfile.jam", """ +lib b : b.cpp ../a//a/shared : static ; """) t.run_build_system() t.expect_addition("bin/$toolset/debug/main.exe") + t.rm(["bin", "a/bin", "b/bin"]) -# Test that putting library in sources of a searched library -# works. -t.write("Jamfile", """ + +# Test that putting a library in sources of a searched library works. +t.write("jamfile.jam", """ exe main : main.cpp png ; lib png : z : png ; lib z : : zzz ; """) + t.run_build_system("-a -d+2", status=None, stderr=None) -# Try to find the "zzz" string either in response file -# (for Windows compilers), or in standard output. +# Try to find the "zzz" string either in response file (for Windows compilers), +# or in the standard output. rsp = t.adjust_names("bin/$toolset/debug/main.exe.rsp")[0] -if os.path.exists(rsp) and string.find(open(rsp).read(), "zzz") != -1: +if os.path.exists(rsp) and ( string.find(open(rsp).read(), "zzz") != -1 ): pass elif string.find(t.stdout(), "zzz") != -1: pass else: t.fail_test(1) -# -# Test main -> libb -> liba chain -# in the case where liba is a file, not a Boost.Build target. -# +# Test main -> libb -> liba chain in the case where liba is a file and not a +# Boost.Build target. t.rm(".") -t.write("Jamroot", "") -t.write("a/Jamfile", """ + +t.write("jamroot.jam", "") + +t.write("a/jamfile.jam", """ lib a : a.cpp ; install dist : a ; """) + t.write("a/a.cpp", """ #if defined(_WIN32) __declspec(dllexport) #endif void a() {} """) + t.run_build_system(subdir="a") t.expect_addition("a/dist/a.dll") -if (os.name == 'nt' or os.uname()[0].lower().startswith('cygwin')) and get_toolset() != 'gcc': +if ( ( os.name == 'nt' ) or os.uname()[0].lower().startswith('cygwin') ) and \ + ( BoostBuild.get_toolset() != 'gcc' ): # This is windows import library -- we know the exact name. file = "a/dist/a.lib" else: file = t.adjust_names(["a/dist/a.dll"])[0] -t.write("b/Jamfile", """ +t.write("b/jamfile.jam", """ lib b : b.cpp ../%s ; """ % file) + t.write("b/b.cpp", """ #if defined(_WIN32) __declspec(dllimport) #endif void a(); - #if defined(_WIN32) __declspec(dllexport) #endif void b() { a(); } """) -t.write("Jamroot", """ +t.write("jamroot.jam", """ exe main : main.cpp b//b ; """) + t.write("main.cpp", """ #if defined(_WIN32) __declspec(dllimport) @@ -160,6 +163,4 @@ int main() { b(); } t.run_build_system() t.expect_addition("bin/$toolset/debug/main.exe") - - t.cleanup() diff --git a/v2/test/library_order.py b/v2/test/library_order.py index f5638a7ba..3a92d2473 100644 --- a/v2/test/library_order.py +++ b/v2/test/library_order.py @@ -1,81 +1,61 @@ #!/usr/bin/python -# Copyright 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 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) -from BoostBuild import Tester, List +# Test that on compilers sensitive to library order on linker's command line, we +# generate the correct order. + +import BoostBuild import string -# Test that on compilers which are sensitive to library order on -# linker's command line, we generate the right order. -t = Tester() +t = BoostBuild.Tester() -t.write("a.cpp", """ +t.write("a.cpp", """ void b(); - -void a() -{ - b(); -} - +void a() { b(); } """) -t.write("b.cpp", """ +t.write("b.cpp", """ void c(); - -void b() -{ - c(); -} +void b() { c(); } """) -t.write("c.cpp", """ +t.write("c.cpp", """ void d(); - -void c() -{ - d(); -} - +void c() { d(); } """) -t.write("d.cpp", """ +t.write("d.cpp", """ void d() {} - """) -# The order of libraries in 'main' is crafted so that -# we get error unless we do something about the order ourselfs. -t.write("Jamfile", """ +# The order of libraries in 'main' is crafted so that we get error unless we do +# something about the order ourselves. +t.write("jamfile.jam", """ exe main : main.cpp libd libc libb liba ; lib libd : d.cpp ; lib libc : c.cpp : static libd ; lib libb : b.cpp : libc ; lib liba : a.cpp : libb ; - """) -t.write("main.cpp", """ +t.write("main.cpp", """ void a(); - -int main() -{ - a(); - return 0; -} - +int main() { a(); } """) -t.write("project-root.jam", """ +t.write("jamroot.jam", """ """) t.run_build_system() t.expect_addition("bin/$toolset/debug/main.exe") -# Test the order between searched libraries -t.write("Jamfile", """ + +# Test the order between searched libraries. +t.write("jamfile.jam", """ exe main : main.cpp png z ; lib png : z : png ; lib z : : zzz ; @@ -84,7 +64,7 @@ lib z : : zzz ; t.run_build_system("-a -n -d+2") t.fail_test(string.find(t.stdout(), "png") > string.find(t.stdout(), "zzz")) -t.write("Jamfile", """ +t.write("jamfile.jam", """ exe main : main.cpp png z ; lib png : : png ; lib z : png : zzz ; @@ -93,12 +73,13 @@ lib z : png : zzz ; t.run_build_system("-a -n -d+2") t.fail_test(string.find(t.stdout(), "png") < string.find(t.stdout(), "zzz")) -# Test the order between prebuilt libraries +# Test the order between prebuilt libraries. t.write("first.a", "") + t.write("second.a", "") -t.write("Jamfile", """ +t.write("jamfile.jam", """ exe main : main.cpp first second ; lib first : second : first.a ; lib second : : second.a ; @@ -107,7 +88,7 @@ lib second : : second.a ; t.run_build_system("-a -n -d+2") t.fail_test(string.find(t.stdout(), "first") > string.find(t.stdout(), "second")) -t.write("Jamfile", """ +t.write("jamfile.jam", """ exe main : main.cpp first second ; lib first : : first.a ; lib second : first : second.a ; @@ -116,7 +97,4 @@ lib second : first : second.a ; t.run_build_system("-a -n -d+2") t.fail_test(string.find(t.stdout(), "first") < string.find(t.stdout(), "second")) - - - t.cleanup() diff --git a/v2/test/library_property.py b/v2/test/library_property.py index fb9e230ce..9430bb705 100644 --- a/v2/test/library_property.py +++ b/v2/test/library_property.py @@ -1,28 +1,26 @@ #!/usr/bin/python -# Copyright 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 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) -# Test that the property has no effect on "obj" targets. -# Previously, it affected all targets, so +# Test that the property has no effect on "obj" targets. Previously, +# it affected all targets, so # -# project : requirements foo ; -# exe a : a.cpp helper ; -# obj helper : helper.cpp : off ; +# project : requirements foo ; +# exe a : a.cpp helper ; +# obj helper : helper.cpp : off ; # -# caused 'foo' to be built with and without optimization. -from BoostBuild import Tester, List +# caused 'foo' to be built with and without optimization. -# Create a temporary working directory -t = Tester() +import BoostBuild -t.write("Jamfile", """ -project - : requirements lib//x - ; +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ +project : requirements lib//x ; exe a : a.cpp foo ; -obj foo : foo.cpp : release ; +obj foo : foo.cpp : release ; """) t.write("a.cpp", """ @@ -35,9 +33,6 @@ void gee(); void aux() { gee(); } """) -t.write("project-root.jam", """ -""") - t.write("lib/x.cpp", """ void #if defined(_WIN32) @@ -46,17 +41,16 @@ __declspec(dllexport) gee() {} """) -t.write("lib/Jamfile", """ +t.write("lib/jamfile.jam", """ lib x : x.cpp ; """) -t.write("lib/project-root.jam", """ +t.write("lib/jamroot.jam", """ """) t.run_build_system() t.expect_addition("bin/$toolset/debug/a.exe") t.expect_nothing("lib/bin/$toolset/release/x.obj") + t.cleanup() - - diff --git a/v2/test/load_dir.py b/v2/test/load_dir.py index 6ee5376d3..09a59f951 100644 --- a/v2/test/load_dir.py +++ b/v2/test/load_dir.py @@ -1,9 +1,8 @@ #!/usr/bin/python """ -Traverses a directory and output the code that would -create the same directory structure during testing. -Assumes that the instance of Tester is called 't'. +Traverses a directory and output the code that would create the same directory +structure during testing. Assumes that the instance of Tester is called 't'. """ import sys @@ -14,6 +13,7 @@ import string def usage(): print "usage: load_dir.py directory" + def remove_first_component(path): result = [path] while 1: @@ -22,8 +22,7 @@ def remove_first_component(path): break result[:1] = list(s) return apply(os.path.join, result[1:]) - - + def create_file(arg, dirname, fnames): for n in fnames: @@ -35,17 +34,17 @@ def create_file(arg, dirname, fnames): print l, print '\n""")\n' -header = """#!/usr/bin/python + +header = """#!/usr/bin/python # Copyright (C) FILL SOMETHING HERE 2005. # 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) -from BoostBuild import Tester, List -import string +import BoostBuild -t = Tester() +t = BoostBuild.Tester() """ footer = """ @@ -56,7 +55,8 @@ t.expect_addition("bin/$toolset/debug/FILL_SOME_HERE.exe") t.cleanup() """ - + + def main(): if len(sys.argv) != 2: usage() @@ -69,16 +69,13 @@ def main(): if not os.path.isdir(path): print "Path '%s' is not a directory" % (path,) - + print header - + os.path.walk(path, create_file, None) print footer + if __name__ == '__main__': main() - - - - diff --git a/v2/test/load_order.py b/v2/test/load_order.py index 25b4ba803..34ceaaf44 100644 --- a/v2/test/load_order.py +++ b/v2/test/load_order.py @@ -5,71 +5,60 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -# Test that we load parent projects before loading children. -from BoostBuild import Tester, List -from string import find +# Test that we load parent projects before loading children. -t = Tester() +import BoostBuild +import string -t.write("Jamfile", """ +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ use-project /child : child ; - ECHO "Setting parent requirements" ; -project - : requirements PASS_THE_TEST - ; - -alias x : child//main ; +project : requirements PASS_THE_TEST ; +alias x : child//main ; """) -t.write("project-root.jam", """ -""") - -t.write("child/Jamfile", """ +t.write("child/jamfile.jam", """ ECHO "Setting child requirements" ; project /child ; - -exe main : main.cpp ; +exe main : main.cpp ; """) -t.write("child/main.cpp", """ +t.write("child/main.cpp", """ #if defined(PASS_THE_TEST) -int main() { return 0; } +int main() {} #endif - """) t.run_build_system() - t.expect_addition("child/bin/$toolset/debug/main.exe") -t.fail_test(find(t.stdout(), "Setting child requirements") < - find(t.stdout(), "Setting parent requirements")) +t.fail_test(string.find(t.stdout(), "Setting child requirements") < + string.find(t.stdout(), "Setting parent requirements")) -# Regression test: parent requirements were ignored in some cases +# Regression test: parent requirements were ignored in some cases. t.rm(".") -t.write("Jamroot", """ -build-project src ; +t.write("jamroot.jam", """ +build-project src ; """) -t.write("src/Jamfile", """ -project : requirements EVERYTHING_OK ; +t.write("src/jamfile.jam", """ +project : requirements EVERYTHING_OK ; """) -t.write("src/app/Jamfile", """ -exe test : test.cpp ; +t.write("src/app/jamfile.jam", """ +exe test : test.cpp ; """) -t.write("src/app/test.cpp", """ +t.write("src/app/test.cpp", """ #ifdef EVERYTHING_OK int main() {} #endif - """) t.run_build_system(subdir="src/app") t.expect_addition("src/app/bin/$toolset/debug/test.exe") - t.cleanup() diff --git a/v2/test/loop.py b/v2/test/loop.py index f45ebea7c..4455b9789 100644 --- a/v2/test/loop.py +++ b/v2/test/loop.py @@ -1,27 +1,26 @@ #!/usr/bin/python -# 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) +# 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) -from BoostBuild import Tester, List -from string import find +import BoostBuild +import string -t = Tester() - - -t.write("project-root.jam", "") -t.write("Jamfile", """ +t = BoostBuild.Tester() +t.write("jamroot.jam", """ lib main : main.cpp l ; -lib l : l.cpp main ; +lib l : l.cpp main ; """) t.write("main.cpp", "") + t.write("l.cpp", "") t.run_build_system("--no-error-backtrace", status=1) -t.fail_test(find(t.stdout(), "error: Recursion in main target references") == -1) -t.fail_test(find(t.stdout(), "./main ./l ./main") == -1) +t.fail_test(string.find(t.stdout(), + "error: Recursion in main target references") == -1) +t.fail_test(string.find(t.stdout(), "./main ./l ./main") == -1) t.cleanup() diff --git a/v2/test/m1-01.py b/v2/test/m1-01.py index 34d82db98..6c42c1eec 100644 --- a/v2/test/m1-01.py +++ b/v2/test/m1-01.py @@ -1,19 +1,18 @@ #!/usr/bin/python -# Copyright 2002 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 2002 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) # Test the very basic 'make' functionality. -from BoostBuild import Tester, List +import BoostBuild + +t = BoostBuild.Tester() -t = Tester() t.set_tree("test1") - -# Check that we can build something - +# Check that we can build something. t.run_build_system("-sTOOLSET=yfc") t.expect_addition("bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj") @@ -33,18 +32,16 @@ t.fail(t.read("bin/a/yfc/debug/runtime-link-dynamic/a") !=\ a.cpp """) -# Check that we have vanilla target names available - +# Check that we have vanilla target names available. t.touch("a.cpp") t.run_build_system("-sTOOLSET a.obj") t.expect_touch("bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj") t.expect_no_modification("bin/a/yfc/debug/runtime-link-dynamic/a") -# Check that if build request cannot be completely matches, a warning is -# issued and subvariant with link-compatible properties is used - -t.write("Jamfile", t.read("Jamfile2")) +# Check that if a build request cannot be completely matches, a warning is +# issued and a subvariant with link-compatible properties is used. +t.write("jamfile.jam", t.read("jamfile2.jam")) stdout="""Warning: cannot exactly satisfy request for ./a with properties off on dynamic yfc debug Using @@ -54,7 +51,7 @@ instead. t.run_build_system("-sTOOLSET=yfc", stdout=stdout) # Check that conflicting link-incompatible requirements prevent building. -t.write("Jamfile", t.read("Jamfile3")) +t.write("jamfile.jam", t.read("jamfile3.jam")) stdout="""Warning: cannot satisfy request for ./a with properties off on dynamic yfc debug Nothing will be built. @@ -62,4 +59,3 @@ Nothing will be built. t.run_build_system("-sTOOLSET=yfc", stdout=stdout, status=1) t.pass_test() - diff --git a/v2/test/m1-02.py b/v2/test/m1-02.py index 86e6312da..13cc9dc1a 100644 --- a/v2/test/m1-02.py +++ b/v2/test/m1-02.py @@ -4,12 +4,13 @@ # 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) -# Tests that 'make' accepts target from other directories and that -# build request for those targets can be overriden. +# Tests that 'make' accepts targets from other directories and that build +# requests for those targets can be overriden. -from BoostBuild import Tester, List +import BoostBuild + +t = BoostBuild.Tester() -t = Tester() t.set_tree("test1") t.run_build_system("-sTOOLSET=yfc") @@ -31,7 +32,6 @@ t.fail(t.read("auxillary/bin/b.obj/yfc/debug/runtime-link-dynamic/b.obj") !=\ b.cpp """) - t.fail(t.read("bin/a/yfc/debug/runtime-link-dynamic/a") !=\ """ off on dynamic yfc debug @@ -41,8 +41,7 @@ a.cpp b.cpp """) -# Check that we have vanilla target names available in subdirs - +# Check that we have vanilla target names available in subdirs. t.touch("auxillary/b.cpp") t.run_build_system("-sTOOLSET b.obj", subdir="auxillary") t.expect_touch("auxillary/bin/b.obj/yfc/debug/runtime-link-dynamic/optimization-space/b.obj") @@ -50,9 +49,8 @@ t.expect_no_modification("bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj") t.expect_no_modification("bin/a/yfc/debug/runtime-link-dynamic/a") -# Check that we cannot request link-incompatible property for source target - -t.write('Jamfile', t.read('Jamfile2')) +# Check that we can not request link-incompatible property for source target. +t.write('jamfile.jam', t.read('jamfile2.jam')) stdout="""Error: subvariant of target ./a with properties off on dynamic yfc debug requests link-incompatible property @@ -61,14 +59,15 @@ for source @auxillary/b.obj """ t.run_build_system("-sTOOLSET=yfc", stdout=stdout) -# Check that if we request link-compatible property then requirement for -# the source target will override it, with warning. This is similar to -# the way build requests are satisfied (see the first test) -# CONSIDER: should be print the main target which requests this one -# (and modifies requiremenets)? -t.write('Jamfile3', t.read('Jamfile3')) -t.write('auxillary/Jamfile3', t.read('auxillary/Jamfile3')) +# Check that if we request link-compatible property then requirement for the +# source target will override it, with a warning. This is similar to the way +# build requests are satisfied (see the first test). +# +# CONSIDER: should be print the main target which requests this one (and +# modifies requirements)? +t.write('jamfile.jam', t.read('jamfile3.jam')) +t.write('auxillary/jamfile.jam', t.read('auxillary/jamfile3.jam')) stdout="""Warning: cannot exactly satisfy request for auxillary/b.obj with properties space on dynamic yfc debug Using @@ -78,15 +77,14 @@ instead. t.run_build_system("-sTOOLSET=yfc", stdout=stdout) -# Check for link-incompatible properties - -t.write('Jamfile4', t.read('Jamfile4')) -t.write('auxillary/Jamfile4', t.read('auxillary/Jamfile4')) +# Check for link-incompatible properties. +t.write('jamfile.jam', t.read('jamfile4.jam')) +t.write('auxillary/jamfile.jam', t.read('auxillary/jamfile4.jam')) stdout="""Warning: cannot satisfy request for auxillary/b.obj with properties space on dynamic yfc debug Nothing will be built. -""") +""" +t.run_build_system("-sTOOLSET=yfc", stdout=stdout) t.pass_test() - diff --git a/v2/test/m1-03.py b/v2/test/m1-03.py index 15b0ff0ed..2f31ba27c 100644 --- a/v2/test/m1-03.py +++ b/v2/test/m1-03.py @@ -1,16 +1,16 @@ #!/usr/bin/python -# Copyright 2002 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 2002 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) -# Tests that we can use objects from other projects -# (i.e. with other project root) -# Test also that we can refer to those target using project-id. +# Tests that we can use objects from other projects, i.e. with other project +# root. Test also that we can refer to those target using project-id. -from BoostBuild import Tester, List +import BoostBuild + +t = BoostBuild.Tester() -t = Tester() t.set_tree("test1") t.run_build_system("-sTOOLSET=yfc", subdir="p1") @@ -39,7 +39,6 @@ t.fail(t.read("p2/bin/c.obj/yfc/debug/runtime-link-dynamic/c.obj") !=\ a.cpp """) - t.fail(t.read("bin/a/yfc/debug/runtime-link-dynamic/a") !=\ """ off on dynamic yfc debug @@ -55,7 +54,4 @@ t.expect_nothing_more() # TODO: need to write test cases for referring to targets using project-id. - - t.pass_test() - diff --git a/v2/test/make_rule.py b/v2/test/make_rule.py index c204d7a40..389200905 100644 --- a/v2/test/make_rule.py +++ b/v2/test/make_rule.py @@ -1,19 +1,18 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# Copyright 2003, 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, 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) -# Test the 'make' rule +# Test the 'make' rule. -from BoostBuild import Tester -from string import find +import BoostBuild +import string -t = Tester(pass_toolset=1) - -t.write("Jamroot", """ +t = BoostBuild.Tester(pass_toolset=1) +t.write("jamroot.jam", """ import feature ; feature.feature test_feature : : free ; @@ -30,32 +29,29 @@ make foo.bar : : creator : 12345678 ; t.run_build_system() t.expect_addition("bin/$toolset/debug/foo.bar") -t.fail_test(find(t.read("bin/$toolset/debug/foo.bar"), "12345678") == -1) +t.fail_test(string.find(t.read("bin/$toolset/debug/foo.bar"), "12345678") == -1) -# Regression test. Make sure that if main target requested two times, -# and build request differ only in incidental properties, the main target -# if created only once. The bug was discovered by Kirill Lapshin. -t.write("Jamroot", """ -# Make sure that incidental property does not -# cause second creation of 'hello1.cpp'. +# Regression test. Make sure that if a main target is requested two times, and +# build requests differ only in incidental properties, the main target is +# created only once. The bug was discovered by Kirill Lapshin. +t.write("jamroot.jam", """ +# Make sure that incidental property does not cause second creation of +# 'hello1.cpp'. exe a : dir//hello1.cpp ; -exe b : dir//hello1.cpp/true ; +exe b : dir//hello1.cpp/true ; """) -t.write("dir/Jamfile", """ +t.write("dir/jamfile.jam", """ import common ; make hello1.cpp : hello.cpp : common.copy ; - """) t.write("dir/hello.cpp", """ -int main() -{ - return 1; -} +int main() {} """) -# Show only names of the actions. + +# Show only action names. t.run_build_system("-d1 -n") t.fail_test(t.stdout().count("copy") != 1) diff --git a/v2/test/module_actions.py b/v2/test/module_actions.py index 1f4ff96a0..9f6da7ebc 100644 --- a/v2/test/module_actions.py +++ b/v2/test/module_actions.py @@ -46,7 +46,7 @@ act t3: X1-global X2-global X3-t3 # Accomodate for that fact. if os.name != 'nt': expected_output = re.sub(spaces_re, " ", expected_output) - expected_output = re.sub(trailing_spaces_re, "\n", expected_output) + expected_output = re.sub(trailing_spaces_re, "\n", expected_output) t.run_build_system(stdout=expected_output) t.expect_nothing_more() diff --git a/v2/test/ndebug.py b/v2/test/ndebug.py index b4d071f80..123576f31 100644 --- a/v2/test/ndebug.py +++ b/v2/test/ndebug.py @@ -1,35 +1,30 @@ #!/usr/bin/python -# 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) +# 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) -# Test that building with optimization brings NDEBUG define, and, more -# importantly, that dependency targets are built with NDEBUG as well, -# even if they are not directly requested. +# Test that building with optimization brings NDEBUG define, and, more +# importantly, that dependency targets are built with NDEBUG as well, even if +# they are not directly requested. +import BoostBuild -from BoostBuild import Tester, List +t = BoostBuild.Tester() - -t = Tester() - -t.write("project-root.jam", "") -t.write("Jamfile", """ +t.write("jamroot.jam", """ exe hello : hello.cpp lib//lib1 ; """) + t.write("hello.cpp", """ #ifdef NDEBUG void foo(); -int main() -{ - foo(); - return 0; -} +int main() { foo(); } #endif """) -t.write("lib/Jamfile", """ -lib lib1 : lib1.cpp ; + +t.write("lib/jamfile.jam", """ +lib lib1 : lib1.cpp ; """) t.write("lib/lib1.cpp", """ #ifdef NDEBUG @@ -37,10 +32,8 @@ void foo() {} #endif """) -# 'release' builds should get NDEBUG define -# use static linking to avoid messing with -# imports/exports on windows. +# 'release' builds should get the NDEBUG define. We use static linking to avoid +# messing with imports/exports on windows. t.run_build_system("link=static release") - t.cleanup() diff --git a/v2/test/no_type.py b/v2/test/no_type.py index 509e93538..0668e53ef 100644 --- a/v2/test/no_type.py +++ b/v2/test/no_type.py @@ -4,17 +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) -# Test that we cannot specify targets of unknown type as sources. -# This is based on the fact that Unix 'ar' will happily consume -# just about anything. +# Test that we cannot specify targets of unknown type as sources. This is based +# on the fact that Unix 'ar' will happily consume just about anything. -from BoostBuild import Tester -t = Tester() +import BoostBuild -t.write("project-root.jam", "import gcc ;") -t.write("Jamfile", """ +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ +import gcc ; static-lib a : a.foo ; """) + t.write("a.foo", "") t.run_build_system(status=1) diff --git a/v2/test/notfile.py b/v2/test/notfile.py index 02b1ee238..ba6509392 100644 --- a/v2/test/notfile.py +++ b/v2/test/notfile.py @@ -1,22 +1,20 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2005. -# 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) +# Copyright (C) Vladimir Prus 2005. +# 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) -# Basic tests for the 'notfile' rule. +# Basic tests for the 'notfile' rule. -from BoostBuild import Tester, List +import BoostBuild import string import os -import fnmatch -t = Tester() +t = BoostBuild.Tester() -t.write("Jamroot", """ +t.write("jamroot.jam", """ import notfile ; - notfile say : "echo hi" ; exe hello : hello.cpp ; @@ -26,19 +24,11 @@ actions valgrind { valgrind $(>) } - """) t.write("hello.cpp", """ - #include - -int main() -{ - std::cout << "Hello!\\n"; - return 1; -} - +int main() { std::cout << "Hello!\\n"; } """) @@ -51,6 +41,4 @@ name = apply(os.path.join, string.split(name, "/")); c = "valgrind " + name t.expect_output_line(c) - t.cleanup() - diff --git a/v2/test/ordered_include.py b/v2/test/ordered_include.py new file mode 100644 index 000000000..3de729532 --- /dev/null +++ b/v2/test/ordered_include.py @@ -0,0 +1,41 @@ +#!/usr/bin/python +# +# Copyright (c) 2008 Steven Watanabe +# +# 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) + +import BoostBuild + +tester = BoostBuild.Tester() + +tester.write("jamroot.jam", """ +obj test : test.cpp : a&&b ; +""") + +tester.write("test.cpp", """ +#include +#include +int main() {} +""") + +tester.write("a/test1.hpp", """ +""") + +tester.write("b/test2.hpp", """ +""") + +tester.run_build_system() + +tester.expect_addition("bin/$toolset/debug/test.obj") + +tester.touch("a/test1.hpp") +tester.run_build_system() +tester.expect_touch("bin/$toolset/debug/test.obj") + +tester.touch("b/test2.hpp") +tester.run_build_system() +tester.expect_touch("bin/$toolset/debug/test.obj") + +tester.cleanup() diff --git a/v2/test/ordered_properties.py b/v2/test/ordered_properties.py index 3025acfba..58ea5a9f1 100644 --- a/v2/test/ordered_properties.py +++ b/v2/test/ordered_properties.py @@ -1,42 +1,30 @@ #!/usr/bin/python -# Copyright 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) - -# This file is template for Boost.Build tests. It creates a simple -# project that builds one exe from one source, and checks that the exe -# is really created. -from BoostBuild import Tester, List +# Copyright 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) # This checks that Boost.Build does not reorder properties # lexicographically. -t = Tester() -t.write("a.cpp", """ +import BoostBuild + +t = BoostBuild.Tester() + +t.write("a.cpp", """ #include - -int main() -{ - foo(); - return 0; -} - +int main() { foo(); } """) -t.write("Jamfile", """ -exe a : a.cpp : d2 d1 ; +t.write("jamroot.jam", """ +exe a : a.cpp : d2 d1 ; """) -t.write("project-root.jam", """ +t.write("d1/a.h", """ """) -t.write("d1/a.h", """ -""") - -t.write("d2/a.h", """ +t.write("d2/a.h", """ inline void foo() {} - """) t.run_build_system() diff --git a/v2/test/out_of_tree.py b/v2/test/out_of_tree.py index 647709870..9e89cefbe 100644 --- a/v2/test/out_of_tree.py +++ b/v2/test/out_of_tree.py @@ -1,41 +1,34 @@ #!/usr/bin/python -# Copyright (C) FILL SOMETHING HERE 2005. -# 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) +# Copyright (C) FILL SOMETHING HERE 2005. +# 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 project when the current directory is outside of -# that project tree, that is: -# bjam some_dir -# works. -from BoostBuild import Tester, List +# Tests that we can build a project when the current directory is outside of +# that project tree, that is 'bjam some_dir' works. -# Create a temporary working directory -t = Tester() +import BoostBuild -# Create the needed files -t.write("p1/Jamroot", """ +# Create a temporary working directory. +t = BoostBuild.Tester() + +# Create the needed files. +t.write("p1/jamroot.jam", """ exe hello : hello.cpp ; """) -t.write("p1/hello.cpp", """ -int main() -{ - return 0; -} +t.write("p1/hello.cpp", """ +int main() {} """) -t.write("p2/Jamroot", """ +t.write("p2/jamroot.jam", """ exe hello2 : hello.cpp ; exe hello3 : hello.cpp ; """) -t.write("p2/hello.cpp", """ -int main() -{ - return 0; -} +t.write("p2/hello.cpp", """ +int main() {} """) t.run_build_system("p1 p2//hello3") diff --git a/v2/test/path_features.py b/v2/test/path_features.py index 582b05e7e..231030be8 100644 --- a/v2/test/path_features.py +++ b/v2/test/path_features.py @@ -5,11 +5,12 @@ # 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) -from BoostBuild import Tester -t = Tester() +import BoostBuild -t.write("project-root.jam", "import gcc ;") -t.write("Jamfile", "lib a : a.cpp : . ;") +t = BoostBuild.Tester() + +t.write("jamroot.jam", "import gcc ;") +t.write("jamfile.jam", "lib a : a.cpp : . ;") t.write("a.cpp", """ #include void @@ -20,21 +21,23 @@ foo() {} """) t.write("a.h", "//empty file\n") -t.write("d/Jamfile", "exe b : b.cpp ..//a ; ") +t.write("d/jamfile.jam", "exe b : b.cpp ..//a ; ") t.write("d/b.cpp", """ - void foo(); - int main() { foo(); } +void foo(); +int main() { foo(); } """) t.run_build_system(subdir="d") -# Now test the path features with condition work as well -t.write("Jamfile", "lib a : a.cpp : debug:. ;") +# Now test the path features with condition work as well. +t.write("jamfile.jam", "lib a : a.cpp : debug:. ;") t.rm("bin") t.run_build_system(subdir="d") -# Test path features with condtion in usage requirements -t.write("Jamfile", "lib a : a.cpp : . : : debug:. ;") +# Test path features with condition in usage requirements. +t.write("jamfile.jam", """ +lib a : a.cpp : . : : debug:. ; +""") t.write("d/b.cpp", """ #include void foo(); @@ -43,11 +46,11 @@ int main() { foo(); } t.rm("d/bin") t.run_build_system(subdir="d") -# Test that absolute paths inside requirements are ok. The problem -# appear only when building targets in subprojects. -t.write("project-root.jam", "") -t.write("Jamfile", "build-project x ; ") -t.write("x/Jamfile", """ +# Test that absolute paths inside requirements are ok. The problems appeared +# only when building targets in subprojects. +t.write("jamroot.jam", "") +t.write("jamfile.jam", "build-project x ; ") +t.write("x/jamfile.jam", """ local pwd = [ PWD ] ; project : requirements $(pwd)/x/include ; exe m : m.cpp : $(pwd)/x/include2 ; @@ -55,7 +58,6 @@ exe m : m.cpp : $(pwd)/x/include2 ; t.write("x/m.cpp", """ #include #include - int main() {} """) t.write("x/include/h1.hpp", "\n") @@ -66,8 +68,8 @@ t.expect_addition("x/bin/$toolset/debug/m.exe") # Test that "&&" in path features is handled correctly. t.rm("bin") -t.write("Jamfile", "build-project sub ;") -t.write("sub/Jamfile", """ +t.write("jamfile.jam", "build-project sub ;") +t.write("sub/jamfile.jam", """ exe a : a.cpp : ../h1&&../h2 ; """) t.write("sub/a.cpp", """ diff --git a/v2/test/pch.py b/v2/test/pch.py index 87ca0846b..d36260a55 100644 --- a/v2/test/pch.py +++ b/v2/test/pch.py @@ -1,63 +1,49 @@ #!/usr/bin/python -# Copyright 2006 Vladimir Prus. -# 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) +# Copyright 2006 Vladimir Prus. +# 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) -from BoostBuild import Tester, List -import string -import os +import BoostBuild -t = Tester() -t.write("Jamroot", """ +t = BoostBuild.Tester() +t.write("jamroot.jam", """ import pch ; - cpp-pch pch : pch.hpp : msvc:pch.cpp . ; - -exe hello : hello.cpp pch : . ; +exe hello : hello.cpp pch : . ; """) -t.write("pch.hpp.bad", """ -THIS WON'T COMPILE +t.write("pch.hpp.bad", """ +THIS WILL NOT COMPILE """) -# Note that pch.hpp is written after pch.hpp.bad, so its timestamp won't -# be less than timestamp of pch.hpp.bad. -t.write("pch.hpp", """ -class TestClass { -public: - TestClass(int, int) {} -}; - -""") - - - -t.write("pch.cpp", """ #include - -""") - -t.write("hello.cpp", """ #include - -int main() +# Note that pch.hpp is written after pch.hpp.bad, so its timestamp will not be +# less than timestamp of pch.hpp.bad. +t.write("pch.hpp", """ +class TestClass { - TestClass c(1, 2); - return 0; -} +public: + TestClass( int, int ) {} +}; +""") +t.write("pch.cpp", """#include +""") + +t.write("hello.cpp", """#include +int main() { TestClass c(1, 2); } """) t.run_build_system() - t.expect_addition("bin/$toolset/debug/hello.exe") -# Now make the header unusable, without changing timestamp. -# If everything is OK, Boost.Build won't recreate PCH, and -# compiler will happily use pre-compiled header, not noticing -# that the real header is bad. + +# Now make the header unusable, without changing timestamp. If everything is OK, +# Boost.Build will not recreate PCH, and compiler will happily use pre-compiled +# header, not noticing that the real header is bad. t.copy_preserving_timestamp("pch.hpp.bad", "pch.hpp") @@ -67,4 +53,3 @@ t.run_build_system() t.expect_addition("bin/$toolset/debug/hello.obj") t.cleanup() - diff --git a/v2/test/prebuilt.py b/v2/test/prebuilt.py index 58590aae7..250cdc820 100644 --- a/v2/test/prebuilt.py +++ b/v2/test/prebuilt.py @@ -6,38 +6,38 @@ # Test that we can use already built sources -from BoostBuild import Tester -t = Tester() +import BoostBuild + +t = BoostBuild.Tester() t.set_tree('prebuilt') -t.expand_toolset("ext/project-root.jam") -t.expand_toolset("project-root.jam") -# First, build the external project +t.expand_toolset("ext/jamroot.jam") +t.expand_toolset("jamroot.jam") + +# First, build the external project. t.run_build_system("debug release", subdir="ext") -# Then pretend that we don't have the sources for the external project, -# and can only use compiled binaries -t.copy("ext/Jamfile2", "ext/Jamfile") -t.expand_toolset("ext/Jamfile") - -# Now check that we can build the main project, and that -# correct prebuilt file is picked, depending of variant. -# This also checks that correct includes for prebuilt -# libraries are used. +# Then pretend that we do not have the sources for the external project, and can +# only use compiled binaries. +t.copy("ext/jamfile2.jam", "ext/jamfile.jam") +t.expand_toolset("ext/jamfile.jam") +# Now check that we can build the main project, and that correct prebuilt file +# is picked, depending of variant. This also checks that correct includes for +# prebuilt libraries are used. t.run_build_system("debug release") t.expect_addition("bin/$toolset/debug/hello.exe") t.expect_addition("bin/$toolset/release/hello.exe") t.rm("bin") -# Now test that prebuilt file specified by absolute name -# works too. -t.copy("ext/Jamfile3", "ext/Jamfile") -t.expand_toolset("ext/Jamfile") + + +# Now test that prebuilt file specified by absolute name works too. +t.copy("ext/jamfile3.jam", "ext/jamfile.jam") +t.expand_toolset("ext/jamfile.jam") t.run_build_system("debug release") t.expect_addition("bin/$toolset/debug/hello.exe") t.expect_addition("bin/$toolset/release/hello.exe") - t.cleanup() diff --git a/v2/test/prebuilt/ext/Jamfile b/v2/test/prebuilt/ext/jamfile.jam similarity index 100% rename from v2/test/prebuilt/ext/Jamfile rename to v2/test/prebuilt/ext/jamfile.jam diff --git a/v2/test/prebuilt/ext/Jamfile2 b/v2/test/prebuilt/ext/jamfile2.jam similarity index 100% rename from v2/test/prebuilt/ext/Jamfile2 rename to v2/test/prebuilt/ext/jamfile2.jam diff --git a/v2/test/prebuilt/ext/Jamfile3 b/v2/test/prebuilt/ext/jamfile3.jam similarity index 100% rename from v2/test/prebuilt/ext/Jamfile3 rename to v2/test/prebuilt/ext/jamfile3.jam diff --git a/v2/test/prebuilt/ext/project-root.jam b/v2/test/prebuilt/ext/jamroot.jam similarity index 100% rename from v2/test/prebuilt/ext/project-root.jam rename to v2/test/prebuilt/ext/jamroot.jam diff --git a/v2/test/prebuilt/Jamfile b/v2/test/prebuilt/jamfile.jam similarity index 100% rename from v2/test/prebuilt/Jamfile rename to v2/test/prebuilt/jamfile.jam diff --git a/v2/test/prebuilt/project-root.jam b/v2/test/prebuilt/jamroot.jam similarity index 100% rename from v2/test/prebuilt/project-root.jam rename to v2/test/prebuilt/jamroot.jam diff --git a/v2/test/print.py b/v2/test/print.py index 62d2c7260..65caf95e1 100644 --- a/v2/test/print.py +++ b/v2/test/print.py @@ -5,12 +5,13 @@ # 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) -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("project-root.jam", "import gcc ;") -t.write("Jamfile", """ +t.write("jamroot.jam", "import gcc ;") + +t.write("jamfile.jam", """ import print ; print.output foo ; print.text \\\"Something\\\" ; @@ -21,7 +22,7 @@ ALWAYS foo ; t.run_build_system() t.expect_content("foo", """\"Something\"""") -t.write("Jamfile", """ +t.write("jamfile.jam", """ import print ; print.output foo ; print.text \\\n\\\"Somethingelse\\\" ; @@ -33,7 +34,7 @@ t.run_build_system() t.expect_content("foo", """\"Something\" \"Somethingelse\"""") -t.write("Jamfile", """ +t.write("jamfile.jam", """ import print ; print.output foo ; print.text \\\"Different\\\" : true ; diff --git a/v2/test/project-test1/dir/Jamfile b/v2/test/project-test1/dir/jamfile.jam similarity index 100% rename from v2/test/project-test1/dir/Jamfile rename to v2/test/project-test1/dir/jamfile.jam diff --git a/v2/test/project-test1/dir2/Jamfile b/v2/test/project-test1/dir2/jamfile.jam similarity index 100% rename from v2/test/project-test1/dir2/Jamfile rename to v2/test/project-test1/dir2/jamfile.jam diff --git a/v2/test/project-test1/dir2/project-root.jam b/v2/test/project-test1/dir2/jamroot.jam similarity index 100% rename from v2/test/project-test1/dir2/project-root.jam rename to v2/test/project-test1/dir2/jamroot.jam diff --git a/v2/test/project-test1/Jamfile b/v2/test/project-test1/jamfile.jam similarity index 100% rename from v2/test/project-test1/Jamfile rename to v2/test/project-test1/jamfile.jam diff --git a/v2/test/project-test1/project-root.jam b/v2/test/project-test1/jamroot.jam similarity index 100% rename from v2/test/project-test1/project-root.jam rename to v2/test/project-test1/jamroot.jam diff --git a/v2/test/project-test3/Jamfile b/v2/test/project-test3/jamfile.jam similarity index 100% rename from v2/test/project-test3/Jamfile rename to v2/test/project-test3/jamfile.jam diff --git a/v2/test/project-test3/project-root.jam b/v2/test/project-test3/jamroot.jam similarity index 100% rename from v2/test/project-test3/project-root.jam rename to v2/test/project-test3/jamroot.jam diff --git a/v2/test/project-test3/lib/Jamfile b/v2/test/project-test3/lib/jamfile.jam similarity index 100% rename from v2/test/project-test3/lib/Jamfile rename to v2/test/project-test3/lib/jamfile.jam diff --git a/v2/test/project-test3/lib2/helper/Jamfile b/v2/test/project-test3/lib2/helper/jamfile.jam similarity index 100% rename from v2/test/project-test3/lib2/helper/Jamfile rename to v2/test/project-test3/lib2/helper/jamfile.jam diff --git a/v2/test/project-test3/lib2/Jamfile b/v2/test/project-test3/lib2/jamfile.jam similarity index 100% rename from v2/test/project-test3/lib2/Jamfile rename to v2/test/project-test3/lib2/jamfile.jam diff --git a/v2/test/project-test3/lib3/Jamfile b/v2/test/project-test3/lib3/jamfile.jam similarity index 100% rename from v2/test/project-test3/lib3/Jamfile rename to v2/test/project-test3/lib3/jamfile.jam diff --git a/v2/test/project-test3/lib3/project-root.jam b/v2/test/project-test3/lib3/jamroot.jam similarity index 100% rename from v2/test/project-test3/lib3/project-root.jam rename to v2/test/project-test3/lib3/jamroot.jam diff --git a/v2/test/project-test4/Jamfile b/v2/test/project-test4/jamfile.jam similarity index 100% rename from v2/test/project-test4/Jamfile rename to v2/test/project-test4/jamfile.jam diff --git a/v2/test/project-test4/Jamfile3 b/v2/test/project-test4/jamfile3.jam similarity index 100% rename from v2/test/project-test4/Jamfile3 rename to v2/test/project-test4/jamfile3.jam diff --git a/v2/test/project-test4/Jamfile4 b/v2/test/project-test4/jamfile4.jam similarity index 100% rename from v2/test/project-test4/Jamfile4 rename to v2/test/project-test4/jamfile4.jam diff --git a/v2/test/project-test4/Jamfile5 b/v2/test/project-test4/jamfile5.jam similarity index 100% rename from v2/test/project-test4/Jamfile5 rename to v2/test/project-test4/jamfile5.jam diff --git a/v2/test/project-test4/project-root.jam b/v2/test/project-test4/jamroot.jam similarity index 100% rename from v2/test/project-test4/project-root.jam rename to v2/test/project-test4/jamroot.jam diff --git a/v2/test/project-test4/lib/Jamfile b/v2/test/project-test4/lib/jamfile.jam similarity index 100% rename from v2/test/project-test4/lib/Jamfile rename to v2/test/project-test4/lib/jamfile.jam diff --git a/v2/test/project-test4/lib/Jamfile1 b/v2/test/project-test4/lib/jamfile1.jam similarity index 100% rename from v2/test/project-test4/lib/Jamfile1 rename to v2/test/project-test4/lib/jamfile1.jam diff --git a/v2/test/project-test4/lib/Jamfile2 b/v2/test/project-test4/lib/jamfile2.jam similarity index 100% rename from v2/test/project-test4/lib/Jamfile2 rename to v2/test/project-test4/lib/jamfile2.jam diff --git a/v2/test/project-test4/lib/Jamfile3 b/v2/test/project-test4/lib/jamfile3.jam similarity index 100% rename from v2/test/project-test4/lib/Jamfile3 rename to v2/test/project-test4/lib/jamfile3.jam diff --git a/v2/test/project-test4/lib2/Jamfile b/v2/test/project-test4/lib2/jamfile.jam similarity index 100% rename from v2/test/project-test4/lib2/Jamfile rename to v2/test/project-test4/lib2/jamfile.jam diff --git a/v2/test/project-test4/lib2/Jamfile2 b/v2/test/project-test4/lib2/jamfile2.jam similarity index 100% rename from v2/test/project-test4/lib2/Jamfile2 rename to v2/test/project-test4/lib2/jamfile2.jam diff --git a/v2/test/project_dependencies.py b/v2/test/project_dependencies.py index e0cdcb686..96df9e250 100644 --- a/v2/test/project_dependencies.py +++ b/v2/test/project_dependencies.py @@ -1,51 +1,51 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# 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, 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) -# Test that we can specify a dependency property -# in project requirements, and that it won't -# cause every main target in the project to -# be generated in it's own subdirectory. +# Test that we can specify a dependency property in project requirements, and +# that it will not cause every main target in the project to be generated in its +# own subdirectory. -# The whole test is somewhat moot now. +# The whole test is somewhat moot now. -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() + +t.write("jamroot.jam", "build-project src ;") + +t.write("lib/jamfile.jam", "lib lib1 : lib1.cpp ;") -t.write("Jamroot", "build-project src ;") -t.write("lib/Jamfile", "lib lib1 : lib1.cpp ;") t.write("lib/lib1.cpp", """ #ifdef _WIN32 __declspec(dllexport) #endif void foo() {}\n """) -t.write("src/Jamfile", """ -project - : requirements ../lib//lib1 - ; - + +t.write("src/jamfile.jam", """ +project : requirements ../lib//lib1 ; exe a : a.cpp ; -exe b : b.cpp ; +exe b : b.cpp ; """) + t.write("src/a.cpp", """ #ifdef _WIN32 __declspec(dllimport) #endif void foo(); -int main() { foo(); return 0; } +int main() { foo(); } """) + t.copy("src/a.cpp", "src/b.cpp") t.run_build_system() -# Test that there's no "main-target-a" part. +# Test that there is no "main-target-a" part. # t.expect_addition("src/bin/$toolset/debug/a.exe") # t.expect_addition("src/bin/$toolset/debug/b.exe") - t.cleanup() diff --git a/v2/test/project_glob.py b/v2/test/project_glob.py index fe76b6870..1445eb2a6 100644 --- a/v2/test/project_glob.py +++ b/v2/test/project_glob.py @@ -5,48 +5,41 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -# Test the 'glob' rule in Jamfile context. -from BoostBuild import Tester, List -import os -import string +# Test the 'glob' rule in Jamfile context. -# Create a temporary working directory -t = Tester() +import BoostBuild -t.write("project-root.jam", """ +# Create a temporary working directory. +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ """) -t.write("Jamfile", """ +t.write("d1/a.cpp", """ +int main() {} """) -t.write("d1/a.cpp", """ -int main() { return 0; } - +t.write("d1/jamfile.jam", """ +exe a : [ glob *.cpp ] ../d2/d//l ; """) -t.write("d1/Jamfile", """ -exe a : [ glob *.cpp ] ../d2/d//l ; -""") - -t.write("d2/d/l.cpp", """ +t.write("d2/d/l.cpp", """ #if defined(_WIN32) __declspec(dllexport) void force_import_lib_creation() {} #endif """) -t.write("d2/d/Jamfile", """ -lib l : [ glob *.cpp ] ; +t.write("d2/d/jamfile.jam", """ +lib l : [ glob *.cpp ] ; """) -t.write("d3/d/Jamfile", """ +t.write("d3/d/jamfile.jam", """ exe a : [ glob ../*.cpp ] ; """) + t.write("d3/a.cpp", """ -int main() -{ - return 0; -} +int main() {} """) t.run_build_system(subdir="d1") @@ -56,49 +49,46 @@ t.run_build_system(subdir="d3/d") t.expect_addition("d3/d/bin/$toolset/debug/a.exe") t.rm("d2/d/bin") + t.run_build_system(subdir="d2/d") t.expect_addition("d2/d/bin/$toolset/debug/l.dll") -# Test that when 'source-location' is explicitly-specified -# glob works relatively to source location + +# Test that when 'source-location' is explicitly-specified glob works relatively +# to the source location. t.rm("d1") -t.write("d1/src/a.cpp", """ -int main() { return 0; } - +t.write("d1/src/a.cpp", """ +int main() {} """) -t.write("d1/Jamfile", """ +t.write("d1/jamfile.jam", """ project : source-location src ; -exe a : [ glob *.cpp ] ../d2/d//l ; +exe a : [ glob *.cpp ] ../d2/d//l ; """) t.run_build_system(subdir="d1") t.expect_addition("d1/bin/$toolset/debug/a.exe") -# Test that wildcards can include directories. Also -# test exclusion patterns. +# Test that wildcards can include directories. Also test exclusion patterns. t.rm("d1") t.write("d1/src/foo/a.cpp", """ void bar(); -int main() { bar(); return 0; } - +int main() { bar(); } """) t.write("d1/src/bar/b.cpp", """ void bar() {} - """) t.write("d1/src/bar/bad.cpp", """ very bad non-compilable file """) - -t.write("d1/Jamfile", """ +t.write("d1/jamfile.jam", """ project : source-location src ; -exe a : [ glob foo/*.cpp bar/*.cpp : bar/bad* ] ../d2/d//l ; +exe a : [ glob foo/*.cpp bar/*.cpp : bar/bad* ] ../d2/d//l ; """) t.run_build_system(subdir="d1") @@ -107,18 +97,20 @@ t.expect_addition("d1/bin/$toolset/debug/a.exe") # Test that 'glob-tree' works. t.rm("d1/bin/$toolset/debug/a.exe") -t.write("d1/Jamfile", """ + +t.write("d1/jamfile.jam", """ project : source-location src ; -exe a : [ glob-tree *.cpp : bad* ] ../d2/d//l ; +exe a : [ glob-tree *.cpp : bad* ] ../d2/d//l ; """) + t.run_build_system(subdir="d1") t.expect_addition("d1/bin/$toolset/debug/a.exe") -# Test that directory names in patterns for -# 'glob-tree' are rejected. -t.write("d1/Jamfile", """ + +# Test that directory names in patterns for 'glob-tree' are rejected. +t.write("d1/jamfile.jam", """ project : source-location src ; -exe a : [ glob-tree foo/*.cpp bar/*.cpp : bad* ] ../d2/d//l ; +exe a : [ glob-tree foo/*.cpp bar/*.cpp : bad* ] ../d2/d//l ; """) t.run_build_system(subdir="d1", status=1) @@ -127,51 +119,40 @@ t.expect_output_line("error: The patterns * may not include directory") t.rm("d1/src/bar/bad.cpp") -# Test that 'glob' works with absolute names +# Test that 'glob' works with absolute names. t.rm("d1/bin") -# Note that to get current dir, we use bjam's PWD, -# not Python's os.getcwd, because the former will -# always return long path. The latter might return -# short path, and that will confuse path.glob. -t.write("d1/Jamfile", """ +# Note that to get current dir, we use bjam's PWD, not Python's os.getcwd(), +# because the former will always return long path while the latter might return +# a short path, and that will confuse path.glob. +t.write("d1/jamfile.jam", """ project : source-location src ; -local pwd = [ PWD ] ; # Always absolute -exe a : [ glob $(pwd)/src/foo/*.cpp $(pwd)/src/bar/*.cpp ] ../d2/d//l ; +local pwd = [ PWD ] ; # Always absolute +exe a : [ glob $(pwd)/src/foo/*.cpp $(pwd)/src/bar/*.cpp ] ../d2/d//l ; """) t.run_build_system(subdir="d1") t.expect_addition("d1/bin/$toolset/debug/a.exe") -# Regression test: glob excludes used to be broken -# when building from a subdirectory. + +# Regression test: glob excludes used to be broken when building from a +# subdirectory. t.rm(".") -t.write("Jamroot", """ +t.write("jamroot.jam", """ build-project p ; """) -t.write("p/p.c", """ -int main() -{ - return 0; -} - - +t.write("p/p.c", """ +int main() {} """) -t.write("p/p_x.c", """ -int main() -{ - return 0; -} - +t.write("p/p_x.c", """ +int main() {} """) -t.write("p/Jamfile", """ -exe p : - [ glob *.c : p_x.c ] - ; +t.write("p/jamfile.jam", """ +exe p : [ glob *.c : p_x.c ] ; """) t.run_build_system(subdir="p") diff --git a/v2/test/project_root_constants.py b/v2/test/project_root_constants.py index 1129ed801..cd8a7d6c7 100644 --- a/v2/test/project_root_constants.py +++ b/v2/test/project_root_constants.py @@ -4,26 +4,25 @@ # 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) -from BoostBuild import Tester, List -from string import find +import BoostBuild +import string -# Create a temporary working directory -t = Tester() +# Create a temporary working directory. +t = BoostBuild.Tester() -# Create the needed files -t.write("project-root.jam", """ +# Create the needed files. +t.write("jamroot.jam", """ constant FOO : foobar gee ; ECHO $(FOO) ; """) -t.write("Jamfile", """ -""") t.run_build_system() -t.fail_test(find(t.stdout(), "foobar gee") == -1) +t.fail_test(string.find(t.stdout(), "foobar gee") == -1) # Regression test: when absolute paths were passed to path-constant rule, -# Boost.Build failed to recognize path as absolute and prepended current dir. -t.write("project-root.jam", """ +# Boost.Build failed to recognize path as absolute and prepended the current +# dir. +t.write("jamroot.jam", """ import path ; local here = [ path.native [ path.pwd ] ] ; path-constant HERE : $(here) ; @@ -34,25 +33,24 @@ if $(HERE) != $(here) EXIT ; } """) -t.write("Jamfile", "") +t.write("jamfile.jam", "") t.run_build_system() -t.write("Jamfile", """ -# This tests that rule 'hello' will be imported -# to children unlocalized, and will still access -# variables in this Jamfile +t.write("jamfile.jam", """ +# This tests that rule 'hello' will be imported to children unlocalized, and +# will still access variables in this Jamfile. x = 10 ; constant FOO : foo ; rule hello ( ) { ECHO "Hello $(x)" ; } """) -t.write("d/Jamfile", """ +t.write("d/jamfile.jam", """ ECHO "d: $(FOO)" ; constant BAR : bar ; """) -t.write("d/d2/Jamfile", """ +t.write("d/d2/jamfile.jam", """ ECHO "d2: $(FOO)" ; ECHO "d2: $(BAR)" ; hello ; diff --git a/v2/test/project_root_rule.py b/v2/test/project_root_rule.py index b2280c3d5..29fdcff4c 100644 --- a/v2/test/project_root_rule.py +++ b/v2/test/project_root_rule.py @@ -1,34 +1,29 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2005. -# 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) +# Copyright (C) Vladimir Prus 2005. +# 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 declare a rule in Jamroot that will be -# can be called in child Jamfile to declare a target. Specifically -# test for use of 'glob' in that rule. -# +# Tests that we can declare a rule in Jamroot that will be can be called in +# child Jamfile to declare a target. Specifically test for use of 'glob' in that +# rule. -from BoostBuild import Tester, List -import string +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("Jamroot", """ + +t.write("jamroot.jam", """ project : requirements static ; - -rule my-lib ( name ) -{ - lib $(name) : [ glob *.cpp ] ; -} +rule my-lib ( name ) { lib $(name) : [ glob *.cpp ] ; } """) -t.write("sub/a.cpp", """ +t.write("sub/a.cpp", """ """) -t.write("sub/Jamfile", """ -my-lib foo ; +t.write("sub/jamfile.jam", """ +my-lib foo ; """) @@ -37,4 +32,3 @@ t.run_build_system(subdir="sub") t.expect_addition("sub/bin/$toolset/debug/link-static/foo.lib") t.cleanup() - diff --git a/v2/test/project_test1.py b/v2/test/project_test1.py index c4a3a8c2f..a2a2ada18 100644 --- a/v2/test/project_test1.py +++ b/v2/test/project_test1.py @@ -5,16 +5,15 @@ # 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) -from BoostBuild import Tester +import BoostBuild import os -t = Tester("--build-system=project-test1", boost_build_path='', pass_toolset=0) - -# This test does no modifications, so run in in the invocation dir +t = BoostBuild.Tester("--build-system=project-test1", boost_build_path='', + pass_toolset=0) +# This test does no modifications, so run in in the invocation dir. os.chdir(t.original_workdir) - expected_output1="""Project Roots: """ @@ -59,16 +58,16 @@ Projects: """ -# Test that correct project structure is created when jam is invoked -# outside of the source tree. +# Test that correct project structure is created when jam is invoked outside of +# the source tree. expected = (expected_output1 + expected_output2 + expected_output3) % \ {"root-dir": "project-test1", "root-dir-prefix": "project-test1/" } t.run_build_system(stdout=expected) -# Test that correct project structure is created when jam is invoked -# at the top of the source tree. +# Test that correct project structure is created when jam is invoked at the top +# of the source tree. expected = (expected_output1 + expected_output3 + expected_output2) % \ {"root-dir": ".", "root-dir-prefix": "" } diff --git a/v2/test/project_test3.py b/v2/test/project_test3.py index 7d46f3f19..8a4421604 100644 --- a/v2/test/project_test3.py +++ b/v2/test/project_test3.py @@ -1,23 +1,21 @@ #!/usr/bin/python -# Copyright 2002, 2003 Dave Abrahams -# Copyright 2002, 2003, 2004, 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 2002, 2003 Dave Abrahams +# Copyright 2002, 2003, 2004, 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) -from BoostBuild import Tester, List +import BoostBuild import os -from string import strip -t = Tester(translate_suffixes=0) +t = BoostBuild.Tester(translate_suffixes=0) -# First check some startup +# First check some startup. t.set_tree("project-test3") -os.remove("project-root.jam") +os.remove("jamroot.jam") t.run_build_system(status=1, stdout= """error: Could not find parent for project at '.' error: Did not find Jamfile.jam or Jamroot.jam in any parent directory. - """) t.set_tree("project-test3") @@ -79,7 +77,6 @@ t.expect_content("lib3/bin/$toolset/debug/f.obj", """$toolset/debug lib3/f.cpp lib2/helper/bin/$toolset/debug/e.obj """) - t.touch("a.cpp") t.run_build_system() @@ -87,11 +84,10 @@ t.expect_touch(["bin/$toolset/debug/a.obj", "bin/$toolset/debug/a.exe", "lib2/bin/$toolset/debug/l.exe"]) - t.run_build_system(extra_args="release optimization=off,speed") -t.expect_addition(["bin/$toolset/release/a.exe", - "bin/$toolset/release/a.obj", - "bin/$toolset/release/optimization-off/a.exe", +t.expect_addition(["bin/$toolset/release/a.exe", + "bin/$toolset/release/a.obj", + "bin/$toolset/release/optimization-off/a.exe", "bin/$toolset/release/optimization-off/a.obj"]) t.run_build_system(extra_args='--clean-all') @@ -102,10 +98,9 @@ t.expect_removal(["bin/$toolset/debug/a.obj", "lib2/bin/$toolset/debug/c.obj", "lib2/bin/$toolset/debug/d.obj", "lib2/bin/$toolset/debug/l.exe", - "lib3/bin/$toolset/debug/f.obj", - ]) + "lib3/bin/$toolset/debug/f.obj"]) -# Now test target ids in command line +# Now test target ids in command line. t.set_tree("project-test3") t.run_build_system("lib//b.obj") t.expect_addition("lib/bin/$toolset/debug/b.obj") @@ -119,22 +114,20 @@ t.run_build_system("lib//b.obj") t.expect_addition("lib/bin/$toolset/debug/b.obj") t.expect_nothing_more() - t.run_build_system("release lib2/helper//e.obj /lib3//f.obj") t.expect_addition("lib2/helper/bin/$toolset/release/e.obj") t.expect_addition("lib3/bin/$toolset/release/f.obj") t.expect_nothing_more() -# Test project ids in command line work as well +# Test project ids in command line work as well. t.set_tree("project-test3") t.run_build_system("/lib2") -t.expect_addition("lib2/bin/$toolset/debug/" * List("c.obj d.obj l.exe")) +t.expect_addition("lib2/bin/$toolset/debug/" * BoostBuild.List("c.obj d.obj l.exe")) t.expect_addition("bin/$toolset/debug/a.obj") t.expect_nothing_more() - t.run_build_system("lib") -t.expect_addition("lib/bin/$toolset/debug/" * List("b.obj m.exe")) +t.expect_addition("lib/bin/$toolset/debug/" * BoostBuild.List("b.obj m.exe")) t.expect_nothing_more() t.cleanup() diff --git a/v2/test/project_test4.py b/v2/test/project_test4.py index ec735df0f..fc4115017 100644 --- a/v2/test/project_test4.py +++ b/v2/test/project_test4.py @@ -1,15 +1,13 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# 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, 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) -from BoostBuild import Tester -import os -from string import strip, find +import BoostBuild -t = Tester(translate_suffixes=0) +t = BoostBuild.Tester(translate_suffixes=0) t.set_tree("project-test4") @@ -40,20 +38,20 @@ t.expect_content("bin/$toolset/debug/b.exe", "bin/$toolset/debug/a.obj\n" ) - -t.copy("lib/Jamfile3", "lib/Jamfile") +t.copy("lib/jamfile3.jam", "lib/jamfile.jam") # Link-compatibility check for rtti is disabled... #t.run_build_system(status=None) -#t.fail_test(find(t.stdout(), +#import string +#t.fail_test(string.find(t.stdout(), #"""warning: targets produced from b.obj are link incompatible #warning: with main target a.exe""") !=-0) -# Test that if we specified composite property in target reference, -# everything works OK. +# Test that if we specified composite property in target reference, everything +# works OK. -t.copy("lib/Jamfile1", "lib/Jamfile") -t.copy("Jamfile5", "Jamfile") +t.copy("lib/jamfile1.jam", "lib/jamfile.jam") +t.copy("jamfile5.jam", "jamfile.jam") t.run_build_system() @@ -64,5 +62,4 @@ t.expect_content("bin/$toolset/debug/a.exe", "bin/$toolset/debug/a.obj lib/bin/$toolset/release/b.obj\n" ) - t.cleanup() diff --git a/v2/test/property_expansion.py b/v2/test/property_expansion.py index 2371d87bd..280f86208 100644 --- a/v2/test/property_expansion.py +++ b/v2/test/property_expansion.py @@ -4,31 +4,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) -from BoostBuild import Tester, List +# Test that free property inside. -# Test that free property inside -t = Tester() +import BoostBuild -t.write("project-root.jam", "") -t.write("Jamfile", """ +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ project ; - variant debug-AA : debug : AA ; - alias all : hello ; exe hello : hello.cpp ; explicit hello ; """) + t.write("hello.cpp", """ #ifdef AA -int main() -{ - return 0; -} +int main() {} #endif """) t.run_build_system("debug-AA") - t.cleanup() diff --git a/v2/test/qt4.py b/v2/test/qt4.py index 0eeed9e9a..abb9594d5 100755 --- a/v2/test/qt4.py +++ b/v2/test/qt4.py @@ -1,18 +1,19 @@ #!/usr/bin/python -# (c) Copyright Juergen Hunold 2008 -# Use, modification, and distribution are subject to 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) +# (c) Copyright Juergen Hunold 2008 +# Use, modification, and distribution are subject to 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) +import BoostBuild import os -from BoostBuild import Tester - -# Run test in real directory in order to find Boost.Test via Boost Top-Level Jamroot +# Run test in real directory in order to find Boost.Test via Boost Top-Level +# Jamroot. qt4_dir = os.getcwd() + "/qt4" -t = Tester(workdir=qt4_dir) +t = BoostBuild.Tester(workdir=qt4_dir) t.run_build_system() + t.cleanup() diff --git a/v2/test/qt4/Jamroot b/v2/test/qt4/jamroot.jam similarity index 100% rename from v2/test/qt4/Jamroot rename to v2/test/qt4/jamroot.jam diff --git a/v2/test/railsys.py b/v2/test/railsys.py index 10db5c3a0..7b7f8bd0b 100644 --- a/v2/test/railsys.py +++ b/v2/test/railsys.py @@ -1,12 +1,12 @@ #!/usr/bin/python -# 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) +# 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) -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() t.set_tree("railsys") t.run_build_system("--v2", subdir="program") diff --git a/v2/test/railsys/libx/project-root.jam b/v2/test/railsys/libx/jamroot.jam similarity index 100% rename from v2/test/railsys/libx/project-root.jam rename to v2/test/railsys/libx/jamroot.jam diff --git a/v2/test/railsys/libx/src/Jamfile b/v2/test/railsys/libx/src/jamfile.jam similarity index 100% rename from v2/test/railsys/libx/src/Jamfile rename to v2/test/railsys/libx/src/jamfile.jam diff --git a/v2/test/railsys/program/Jamfile b/v2/test/railsys/program/jamfile.jam similarity index 100% rename from v2/test/railsys/program/Jamfile rename to v2/test/railsys/program/jamfile.jam diff --git a/v2/test/railsys/program/project-root.jam b/v2/test/railsys/program/jamroot.jam similarity index 100% rename from v2/test/railsys/program/project-root.jam rename to v2/test/railsys/program/jamroot.jam diff --git a/v2/test/railsys/program/liba/Jamfile b/v2/test/railsys/program/liba/jamfile.jam similarity index 100% rename from v2/test/railsys/program/liba/Jamfile rename to v2/test/railsys/program/liba/jamfile.jam diff --git a/v2/test/railsys/program/main/Jamfile b/v2/test/railsys/program/main/jamfile.jam similarity index 100% rename from v2/test/railsys/program/main/Jamfile rename to v2/test/railsys/program/main/jamfile.jam diff --git a/v2/test/rebuilds.py b/v2/test/rebuilds.py index 9de1e32b7..da64eada3 100644 --- a/v2/test/rebuilds.py +++ b/v2/test/rebuilds.py @@ -1,10 +1,8 @@ #!/usr/bin/python -# Copyright 2005 Dave Abrahams -# 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 tests the typechecking facilities. +# Copyright 2005 Dave Abrahams +# 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 BoostBuild diff --git a/v2/test/regression.py b/v2/test/regression.py index 9ef3bed7f..c65082810 100644 --- a/v2/test/regression.py +++ b/v2/test/regression.py @@ -5,52 +5,45 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -# Test for the regression testing framework. -from BoostBuild import Tester, List +# Test for the regression testing framework. -# Create a temporary working directory -t = Tester() +import BoostBuild -t.write("c.cpp", "") +# Create a temporary working directory. +t = BoostBuild.Tester() + +t.write("c.cpp", "\n") t.write("r.cpp", """ - void helper(); #include -int main(int ac, char* av[]) +int main( int ac, char * av[] ) { helper(); - - for (int i = 1; i < ac; ++i) - std::cout << av[i] << '\\n'; - return 0; -} + for ( int i = 1; i < ac; ++i ) + std::cout << av[ i ] << '\\n'; +} """) -t.write("c-f.cpp", """ -int +t.write("c-f.cpp", """ +int """) -t.write("r-f.cpp", """ -int main() -{ - return 1; -} +t.write("r-f.cpp", """ +int main() { return 1; } """) -t.write("Jamfile", """ +t.write("jamfile.jam", """ import testing ; - compile c.cpp ; compile-fail c-f.cpp ; run r.cpp libs//helper : foo bar ; run-fail r-f.cpp ; - """) -t.write("libs/Jamfile", """ +t.write("libs/jamfile.jam", """ lib helper : helper.cpp ; """) @@ -60,10 +53,9 @@ void __declspec(dllexport) #endif helper() {} - """) -t.write("project-root.jam", "") +t.write("jamroot.jam", "") # First test that when outcomes are expected, all .test files are created. t.run_build_system("hardcode-dll-paths=false", stderr=None, status=None) @@ -74,28 +66,26 @@ t.expect_addition("bin/r-f.test/$toolset/debug/r-f.test") # Make sure args are handled. t.expect_content("bin/r.test/$toolset/debug/r.output", - "foo\nbar\n*\nEXIT STATUS: 0*\n",True) + "foo\nbar\n*\nEXIT STATUS: 0*\n", True) # Test that input file is handled as well. t.write("r.cpp", """ #include #include -int main(int ac, char* av[]) +int main( int ac, char * av[] ) { - for (int i = 1; i < ac; ++i) { - std::ifstream ifs(av[i]); + for ( int i = 1; i < ac; ++i ) + { + std::ifstream ifs( av[ i ] ); std::cout << ifs.rdbuf(); } - - return 0; -} +} """) t.write("dir/input.txt", "test input") -t.write("Jamfile", """ +t.write("jamfile.jam", """ import testing ; - compile c.cpp ; obj c-obj : c.cpp ; compile-fail c-f.cpp ; @@ -112,9 +102,9 @@ t.expect_content("bin/r.test/$toolset/debug/r.output", t.expect_addition('bin/$toolset/debug/execution.time') t.expect_addition('bin/$toolset/debug/compilation.time') -# Make sure test failures are detected. Reverse expectation and see -# if .test files are created or not. -t.write("Jamfile", """ +# Make sure test failures are detected. Reverse expectation and see if .test +# files are created or not. +t.write("jamfile.jam", """ import testing ; compile-fail c.cpp ; @@ -123,7 +113,7 @@ run-fail r.cpp : : dir/input.txt ; run r-f.cpp ; """) -t.touch(List("c.cpp c-f.cpp r.cpp r-f.cpp")) +t.touch(BoostBuild.List("c.cpp c-f.cpp r.cpp r-f.cpp")) t.run_build_system("hardcode-dll-paths=false", stderr=None, status=1) t.expect_removal("bin/c.test/$toolset/debug/c.test") diff --git a/v2/test/relative_sources.py b/v2/test/relative_sources.py index e03f999bc..6ffe3619b 100644 --- a/v2/test/relative_sources.py +++ b/v2/test/relative_sources.py @@ -1,18 +1,19 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# Copyright 2002, 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 2002, 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) # Test that we can specify sources using relative names. -from BoostBuild import Tester -t = Tester() +import BoostBuild -t.write("project-root.jam", "import gcc ;") -t.write("Jamfile", "exe a : src/a.cpp ;") -t.write("src/a.cpp", "int main() { return 0; }\n") +t = BoostBuild.Tester() + +t.write("jamroot.jam", "import gcc ;") +t.write("jamfile.jam", "exe a : src/a.cpp ;") +t.write("src/a.cpp", "int main() {}\n") t.run_build_system() diff --git a/v2/test/remove_requirement.py b/v2/test/remove_requirement.py index 24a3deb96..b060a2ab7 100644 --- a/v2/test/remove_requirement.py +++ b/v2/test/remove_requirement.py @@ -1,76 +1,58 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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) -from BoostBuild import Tester, List -import string +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -t.write("Jamroot", """ + +t.write("jamroot.jam", """ project : requirements multi debug:static ; build-project sub ; build-project sub2 ; build-project sub3 ; -build-project sub4 ; +build-project sub4 ; """) -t.write("sub/Jamfile", """ -exe hello : hello.cpp : -multi ; +t.write("sub/jamfile.jam", """ +exe hello : hello.cpp : -multi ; """) -t.write("sub/hello.cpp", """ -int main() -{ - return 0; -} - +t.write("sub/hello.cpp", """ +int main() {} """) -t.write("sub2/Jamfile", """ +t.write("sub2/jamfile.jam", """ project : requirements -multi ; -exe hello : hello.cpp ; +exe hello : hello.cpp ; """) -t.write("sub2/hello.cpp", """ -int main() -{ - return 0; -} - +t.write("sub2/hello.cpp", """ +int main() {} """) -t.write("sub3/hello.cpp", """ -int main() -{ - return 0; -} - +t.write("sub3/hello.cpp", """ +int main() {} """) -t.write("sub3/Jamfile", """ -exe hello : hello.cpp : -debug:static ; +t.write("sub3/jamfile.jam", """ +exe hello : hello.cpp : -debug:static ; """) -t.write("sub4/hello.cpp", """ -int main() -{ - return 0; -} - +t.write("sub4/hello.cpp", """ +int main() {} """) -t.write("sub4/Jamfile", """ +t.write("sub4/jamfile.jam", """ project : requirements -debug:static ; -exe hello : hello.cpp ; +exe hello : hello.cpp ; """) - - t.run_build_system() t.expect_addition("sub/bin/$toolset/debug/link-static/hello.exe") @@ -81,29 +63,22 @@ t.expect_addition("sub4/bin/$toolset/debug/threading-multi/hello.exe") t.rm(".") # Now test that path requirements can be removed as well. -t.write("Jamroot", """ +t.write("jamroot.jam", """ build-project sub ; - """) -t.write("sub/Jamfile", """ +t.write("sub/jamfile.jam", """ project : requirements broken ; - -exe hello : hello.cpp : -broken ; +exe hello : hello.cpp : -broken ; """) -t.write("sub/hello.cpp", """ +t.write("sub/hello.cpp", """ #include "math.h" - -int main() -{ - return 0; -} - +int main() {} """) -t.write("sub/broken/math.h", """ -Broken +t.write("sub/broken/math.h", """ +Broken """) @@ -112,4 +87,3 @@ t.run_build_system() t.expect_addition("sub/bin/$toolset/debug/hello.exe") t.cleanup() - diff --git a/v2/test/resolution.py b/v2/test/resolution.py index 93c520b26..31c122e19 100644 --- a/v2/test/resolution.py +++ b/v2/test/resolution.py @@ -1,28 +1,27 @@ #!/usr/bin/python -# Copyright (C) Vladimir Prus 2006. -# 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) +# Copyright (C) Vladimir Prus 2006. +# 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 for the target id resolution process. -from BoostBuild import Tester, List +# Tests for the target id resolution process. -# Create a temporary working directory -t = Tester() +import BoostBuild + +# Create a temporary working directory. +t = BoostBuild.Tester() # Create the needed files -t.write("Jamroot", """ +t.write("jamroot.jam", """ exe hello : hello.cpp ; -# This should use the 'hello' target, even if there's -# 'hello' file in current dir. +# This should use the 'hello' target, even if there is a 'hello' file in the +# current dir. install s : hello : . ; """) + t.write("hello.cpp", """ -int main() -{ - return 0; -} +int main() {} """) t.run_build_system() @@ -31,8 +30,8 @@ t.expect_addition("bin/$toolset/debug/hello.obj") t.touch("hello.cpp") t.run_build_system("s") -# If 'hello' in the 's' target resolved to file in -# current dir, nothing will be rebuilt. +# If 'hello' in the 's' target resolved to file in the current dir, nothing will +# be rebuilt. t.expect_touch("bin/$toolset/debug/hello.obj") t.cleanup() diff --git a/v2/test/searched_lib.py b/v2/test/searched_lib.py index 32058dab8..7f96b0a88 100644 --- a/v2/test/searched_lib.py +++ b/v2/test/searched_lib.py @@ -8,14 +8,16 @@ # Test usage of searched-libs: one which are found via -l # switch to the linker/compiler. -from BoostBuild import Tester, get_toolset -import string +import BoostBuild import os -t = Tester() +import string + +t = BoostBuild.Tester() + # To start with, we have to prepare a library to link with. -t.write("lib/project-root.jam", "") -t.write("lib/Jamfile", "lib test_lib : test_lib.cpp ;") +t.write("lib/jamroot.jam", "") +t.write("lib/jamfile.jam", "lib test_lib : test_lib.cpp ;") t.write("lib/test_lib.cpp", """ #ifdef _WIN32 __declspec(dllexport) @@ -26,9 +28,11 @@ void foo() {} t.run_build_system(subdir="lib") t.expect_addition("lib/bin/$toolset/debug/test_lib.dll") + # Auto adjusting of suffixes does not work, since we need to # change dll to lib. -if (os.name == 'nt' or os.uname()[0].lower().startswith('cygwin')) and get_toolset() != 'gcc': +if ( ( os.name == "nt" ) or os.uname()[0].lower().startswith("cygwin") ) and \ + ( BoostBuild.get_toolset() != "gcc" ): t.copy("lib/bin/$toolset/debug/test_lib.implib", "lib/test_lib.implib") t.copy("lib/bin/$toolset/debug/test_lib.dll", "lib/test_lib.dll") else: @@ -36,9 +40,9 @@ else: # Test that the simplest usage of searched library works. -t.write('project-root.jam', '') -t.write('Jamfile', """ +t.write("jamroot.jam", "") +t.write("jamfile.jam", """ import path ; import project ; @@ -49,26 +53,28 @@ exe main : main.cpp helper ; lib helper : helper.cpp test_lib ; lib test_lib : : test_lib lib ; """) + t.write("main.cpp", """ void helper(); -int main() { helper(); return 0; } +int main() { helper(); } """) + t.write("helper.cpp", """ void foo(); - void #if defined(_WIN32) __declspec(dllexport) #endif helper() { foo(); } """) + t.run_build_system() t.expect_addition("bin/$toolset/debug/main.exe") t.rm("bin/$toolset/debug/main.exe") -# Test that 'unit-test' will correctly add runtime paths -# to searched libraries. -t.write('Jamfile', """ + +# Test that 'unit-test' will correctly add runtime paths to searched libraries. +t.write("jamfile.jam", """ import path ; import project ; @@ -83,44 +89,43 @@ unit-test main : main.cpp helper ; lib helper : helper.cpp test_lib ; lib test_lib : : test_lib lib ; """) + t.run_build_system() t.expect_addition("bin/$toolset/debug/main.passed") t.rm("bin/$toolset/debug/main.exe") -# Now try using searched lib from static lib. Request shared version -# of searched lib, since we don't have static one handy. -t.write('Jamfile', """ +# Now try using searched lib from static lib. Request shared version of searched +# lib, since we do not have a static one handy. +t.write("jamfile.jam", """ exe main : main.cpp helper ; lib helper : helper.cpp test_lib/shared : static ; lib test_lib : : test_lib lib ; """) + t.run_build_system(stderr=None) t.expect_addition("bin/$toolset/debug/main.exe") t.expect_addition("bin/$toolset/debug/link-static/helper.lib") t.rm("bin/$toolset/debug/main.exe") -# A regression test: property referring to -# searched-lib was mishandled. As the result, we were -# putting target name to the command line! +# A regression test: property referring to searched-lib was being +# mishandled. As the result, we were putting target name to the command line! # Note that # g++ ...... <.>z -# works nicely in some cases, sending output from compiler -# to file 'z'. -# This problem shows up when searched libs are in usage -# requirements. - -t.write('Jamfile', 'exe main : main.cpp d/d2//a ;') -t.write('main.cpp',""" +# works nicely in some cases, sending output from compiler to file 'z'. This +# problem shows up when searched libs are in usage requirements. +t.write("jamfile.jam", "exe main : main.cpp d/d2//a ;") +t.write("main.cpp", """ void foo(); -int main() { foo(); return 0; } - +int main() { foo(); } """) -t.write('d/d2/Jamfile', """ + +t.write("d/d2/jamfile.jam", """ lib test_lib : : test_lib ../../lib ; lib a : a.cpp : : : test_lib ; """) -t.write('d/d2/a.cpp', """ + +t.write("d/d2/a.cpp", """ #ifdef _WIN32 __declspec(dllexport) int force_library_creation_for_a; #endif @@ -128,39 +133,36 @@ __declspec(dllexport) int force_library_creation_for_a; t.run_build_system() -# A regression test. Searched targets were not associated -# with any properties. For that reason, if the same searched -# lib is generated with two different properties, we had an -# error saying they are actualized to the same Jam target name. -t.write("project-root.jam", "") +# A regression test. Searched targets were not associated with any properties. +# For that reason, if the same searched lib is generated with two different +# properties, we had an error saying they are actualized to the same Jam target +# name. +t.write("jamroot.jam", "") t.write("a.cpp", "") -# The 'l' library will be built in two variants: -# 'debug' (directly requested) and 'release' (requested -# from 'a'). -t.write("Jamfile", """ +# The 'l' library will be built in two variants: 'debug' (directly requested) +# and 'release' (requested from 'a'). +t.write("jamfile.jam", """ exe a : a.cpp l/release ; - lib l : : l_d debug ; lib l : : l_r release ; """) t.run_build_system("-n") -# A regression test. Two virtual target with the same properties -# were created for 'l' target, which caused and error to be reported -# when actualizing targets. The final error is correct, but we should -# not create two duplicated targets. Thanks to Andre Hentz -# for finding this bug. -t.write("project-root.jam", "") + +# A regression test. Two virtual target with the same properties were created +# for 'l' target, which caused and error to be reported when actualizing +# targets. The final error is correct, but we should not create two duplicated +# targets. Thanks to Andre Hentz for finding this bug. +t.write("jamroot.jam", "") t.write("a.cpp", "") -t.write("Jamfile", """ +t.write("jamfile.jam", """ project a : requirements static ; - static-lib a : a.cpp l ; lib l : : l_f ; """) @@ -168,19 +170,22 @@ lib l : : l_f ; t.run_build_system("-n") -# Make sure that plain "lib foobar ; " works. -t.write("Jamfile", """ +# Make sure plain "lib foobar ; " works. +t.write("jamfile.jam", """ exe a : a.cpp foobar ; lib foobar ; """) + t.run_build_system("-n -d2") t.fail_test(string.find(t.stdout(), "foobar") == -1) -# Make sure that plain "lib foo bar ; " works. -t.write("Jamfile", """ + +# Make sure plain "lib foo bar ; " works. +t.write("jamfile.jam", """ exe a : a.cpp foo bar ; lib foo bar ; """) + t.run_build_system("-n -d2") t.fail_test(string.find(t.stdout(), "foo") == -1) t.fail_test(string.find(t.stdout(), "bar") == -1) diff --git a/v2/test/skipping.py b/v2/test/skipping.py index 0c74a89f4..b3575eafd 100644 --- a/v2/test/skipping.py +++ b/v2/test/skipping.py @@ -1,40 +1,36 @@ #!/usr/bin/python -# 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) +# 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) -# Test that V2 does not fail gracelessy when any target is skipped. -from BoostBuild import Tester, List +# Test that V2 does not fail gracelessy when any target is skipped. -# Create a temporary working directory -t = Tester() -t.write("a.cpp", """ -int main() {} +import BoostBuild + +# Create a temporary working directory. +t = BoostBuild.Tester() + +t.write("a.cpp", """ +int main() {} """) -t.write("b.cpp", """ -int main() {} +t.write("b.cpp", """ +int main() {} """) -t.write("c.cpp", """ -int main() {} +t.write("c.cpp", """ +int main() {} """) -t.write("Jamfile", """ -import feature : feature ; - -feature foo : 1 2 : link-incompatible ; - +t.write("jamroot.jam", """ +import feature ; +feature.feature foo : 1 2 : link-incompatible ; exe a : a.cpp : 1 ; exe b : b.cpp : 2 ; -exe c : c.cpp ; -""") - -t.write("project-root.jam", """ +exe c : c.cpp ; """) t.run_build_system("foo=1") t.cleanup() - diff --git a/v2/test/sort_rule.py b/v2/test/sort_rule.py index d38b4e5c6..f4a4acda1 100755 --- a/v2/test/sort_rule.py +++ b/v2/test/sort_rule.py @@ -20,7 +20,8 @@ import BoostBuild def testSORTCorrectness(): """Testing that Boost Jam's SORT builtin rule actually sorts correctly. """ - t = BoostBuild.Tester("-f test.jam -d1", pass_toolset=False, use_test_config=False) + t = BoostBuild.Tester("-f test.jam -d1", pass_toolset=False, + use_test_config=False) t.write("test.jam", """ NOCARE all ; @@ -57,7 +58,8 @@ def testSORTDuration(): """Regression test making sure Boost Jam's SORT builtin rule does not get quadratic behaviour again in this use case. """ - t = BoostBuild.Tester("-f test.jam -d1", pass_toolset=False, use_test_config=False) + t = BoostBuild.Tester("-f test.jam -d1", pass_toolset=False, + use_test_config=False) f = open(t.workpath("test.jam"), "w") print >> f, "data = " diff --git a/v2/test/source_locations.py b/v2/test/source_locations.py index d1ce9b86f..7133ab044 100644 --- a/v2/test/source_locations.py +++ b/v2/test/source_locations.py @@ -7,45 +7,34 @@ # Test that projects with multiple source-location directories are handled OK. -from BoostBuild import Tester -t = Tester() +import BoostBuild -t.write("Jamroot", """ +t = BoostBuild.Tester() + +t.write("jamroot.jam", """ path-constant SRC1 : "./src1" ; path-constant SRC2 : "./src2" ; path-constant SRC3 : "./src3" ; path-constant BUILD : "build" ; -project - : requirements - $(SRC1)/include - multi - : build-dir $(BUILD) - ; +project : requirements $(SRC1)/include multi + : build-dir $(BUILD) ; build-project project1 ; - """) -t.write("project1/Jamfile", """ -project project1 - : source-location $(SRC1) - $(SRC2) - $(SRC3) - ; -SRCS = s1.cpp - s2.cpp - testfoo.cpp - ; +t.write("project1/jamfile.jam", """ +project project1 : source-location $(SRC1) $(SRC2) $(SRC3) ; +SRCS = s1.cpp s2.cpp testfoo.cpp ; exe test : $(SRCS) ; """) -t.write("src1/s1.cpp", "int main() { return 0; }\n") +t.write("src1/s1.cpp", "int main() {}\n") t.write("src2/s2.cpp", "void hello() {}\n") t.write("src3/testfoo.cpp", "void testfoo() {}\n") -# This file should not be picked up, because "src2" is before -# "src3" in the list of source directories. +# This file should not be picked up, because "src2" is before "src3" in the list +# of source directories. t.write("src3/s2.cpp", "void hello() {}\n") t.run_build_system() diff --git a/v2/test/stage.py b/v2/test/stage.py index ba7ff693f..9862138b0 100644 --- a/v2/test/stage.py +++ b/v2/test/stage.py @@ -1,20 +1,19 @@ #!/usr/bin/python -# Copyright 2003 Dave Abrahams -# 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 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) -# Test staging +# Test staging. -from BoostBuild import Tester -t = Tester() +import BoostBuild -t.write("project-root.jam", "import gcc ;") +t = BoostBuild.Tester() -t.write( - "Jamfile", -""" +t.write("jamroot.jam", "import gcc ;") + +t.write("jamfile.jam", """ lib a : a.cpp ; stage dist : a a.h auxilliary/1 ; """) @@ -36,25 +35,21 @@ t.run_build_system() t.expect_addition(["dist/a.dll", "dist/a.h", "dist/1"]) -# Regression test: the following was causing the "duplicate target name" -# error. -t.write( - "Jamfile", -""" +# Regression test: the following was causing the "duplicate target name" error. +t.write("jamfile.jam", """ project : requirements true ; lib a : a.cpp ; stage dist : a a.h auxilliary/1 ; alias dist-alias : dist ; """) + t.run_build_system() -# Test the property -t.write("Jamfile", """ +# Test the property. +t.write("jamfile.jam", """ lib a : a.cpp ; -stage dist : a - : debug:ds release:rs - ; +stage dist : a : debug:ds release:rs ; """) t.run_build_system() @@ -63,62 +58,60 @@ t.expect_addition("ds/a.dll") t.run_build_system("release") t.expect_addition("rs/a.dll") -# Test the property in subprojects. -# Thanks to Kirill Lapshin for bug report. -t.write("project-root.jam", """ +# Test the property in subprojects. Thanks to Kirill Lapshin for the +# bug report. + +t.write("jamroot.jam", """ path-constant DIST : dist ; """) -t.write("Jamfile", "build-project d ;") +t.write("jamfile.jam", "build-project d ;") -t.write( - "d/Jamfile", -""" +t.write("d/jamfile.jam", """ exe a : a.cpp ; stage dist : a : $(DIST) ; """) -t.write("d/a.cpp", "int main() { return 0;}\n") +t.write("d/a.cpp", "int main() {}\n") t.run_build_system() t.expect_addition("dist/a.exe") t.rm("dist") -# Workaround a BIG BUG: the response file is not deleted, -# even if application *is* deleted. We'll try to use the -# same response file when building from subdir, with very -# bad results. + +# Workaround a BIG BUG: the response file is not deleted, even if application +# *is* deleted. We will try to use the same response file when building from +# subdir, with very bad results. t.rm("d/bin") t.run_build_system(subdir="d") t.expect_addition("dist/a.exe") # Check that 'stage' does not incorrectly reset target suffixes. -t.write("a.cpp", """ -int main() {} +t.write("a.cpp", """ +int main() {} """) -t.write("project-root.jam", """ +t.write("jamroot.jam", """ import type ; type.register MYEXE : : EXE ; -type.set-generated-target-suffix MYEXE : off : myexe ; +type.set-generated-target-suffix MYEXE : off : myexe ; """) -# Since off is in properties when 'a' is built, and staged, -# it's suffix should be "myexe". -t.write("Jamfile", """ +# Since off is in properties when 'a' is built, and staged, its +# suffix should be "myexe". +t.write("jamfile.jam", """ stage dist : a ; -myexe a : a.cpp ; +myexe a : a.cpp ; """) t.run_build_system() t.expect_addition("dist/a.myexe") # Test 'stage's ability to traverse dependencies. -t.write("a.cpp", """ -int main() { return 0; } - +t.write("a.cpp", """ +int main() {} """) t.write("l.cpp", """ @@ -126,43 +119,45 @@ void #if defined(_WIN32) __declspec(dllexport) #endif -foo() { } - +foo() {} """) -t.write("Jamfile", """ +t.write("jamfile.jam", """ lib l : l.cpp ; exe a : a.cpp l ; -stage dist : a : on EXE LIB ; +stage dist : a : on EXE LIB ; """) -t.write("project-root.jam", "") +t.write("jamroot.jam", "") t.rm("dist") + t.run_build_system() t.expect_addition("dist/a.exe") t.expect_addition("dist/l.dll") -# Check that properties are ignored the traversing -# target for staging. +# Check that properties are ignored the traversing target for staging. t.copy("l.cpp", "l2.cpp") + t.copy("l.cpp", "l3.cpp") -t.write("Jamfile", """ + +t.write("jamfile.jam", """ lib l2 : l2.cpp ; lib l3 : l3.cpp ; lib l : l.cpp : l2 l3 ; exe a : a.cpp l ; -stage dist : a : on EXE LIB ; +stage dist : a : on EXE LIB ; """) t.rm("dist") + t.run_build_system() t.expect_addition("dist/l3.dll") t.expect_nothing("dist/l2.dll") # Check if on 'stage' works. t.rm(".") -t.write("Jamroot", """ +t.write("jamroot.jam", """ stage a1 : a1.txt : dist ; stage a2 : a2.txt : dist a1 ; """) @@ -171,77 +166,93 @@ t.write("a2.txt", "") t.run_build_system("a2") t.expect_addition(["dist/a1.txt", "dist/a2.txt"]) -# Regression test: check if . works +# Regression test: check that . works. t.rm(".") -t.write("Jamroot", """ + +t.write("jamroot.jam", """ stage a1 : d/a1.txt : . ; """) + t.write("d/a1.txt", "") + t.run_build_system() t.expect_addition("a1.txt") -# Test that relative paths of sources can be preserved +# Test that relative paths of sources can be preserved. t.rm(".") -t.write("Jamroot", """ + +t.write("jamroot.jam", """ install dist : a/b/c.h : . ; """) + t.write("a/b/c.h", "") + t.run_build_system() t.expect_addition("dist/a/b/c.h") -t.write("Jamroot", """ +t.write("jamroot.jam", """ install dist : a/b/c.h : a ; """) + t.write("a/b/c.h", "") + t.run_build_system() t.expect_addition("dist/b/c.h") t.rm(".") -t.write("build/Jamroot", """ -install dist : ../a/b/c.h - : ../dist ../a ; +t.write("build/jamroot.jam", """ +install dist : ../a/b/c.h : ../dist ../a ; """) + t.write("a/b/c.h", "") + t.run_build_system(subdir="build") t.expect_addition("dist/b/c.h") -t.write("Jamroot", """ +t.write("jamroot.jam", """ install dist2 : a/b/c.h : a ; """) + t.write("a/b/c.h", "") -t.write("sub/Jamfile", """ + +t.write("sub/jamfile.jam", """ alias h : ..//dist2 ; """) + t.run_build_system(subdir="sub") t.expect_addition("dist2/b/c.h") -# Test that when installing .cpp files, we don't scan -# include dependencies. +# Test that when installing .cpp files, we do not scan include dependencies. t.rm(".") -t.write("Jamroot", """ + +t.write("jamroot.jam", """ install dist : a.cpp ; """) + t.write("a.cpp", """ #include "a.h" """) + t.write("a.h", "") + t.run_build_system() t.expect_addition("dist/a.cpp") t.touch("a.h") + t.run_build_system() t.expect_nothing("dist/a.cpp") -# Test that property works, when there's just -# one file in sources. +# Test that property works, when there is just one file in sources. t.rm(".") -t.write("Jamroot", """ + +t.write("jamroot.jam", """ install dist : a.cpp : b.cpp ; """) -t.write("a.cpp", "test file") -t.run_build_system() +t.write("a.cpp", "test file") + +t.run_build_system() t.expect_addition("dist/b.cpp") t.cleanup() - diff --git a/v2/test/standalone.py b/v2/test/standalone.py index 70a95ee88..785bab597 100644 --- a/v2/test/standalone.py +++ b/v2/test/standalone.py @@ -1,29 +1,26 @@ #!/usr/bin/python -# 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) +# 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) -from BoostBuild import Tester, List +import BoostBuild + +t = BoostBuild.Tester() -t = Tester() # Regression tests: standalone project were not able to refer to targets -# declared in themselfs! - -t.write("a.cpp", """ -int main() -{ - return 0; -} +# declared in themselves. +t.write("a.cpp", """ +int main() {} """) -t.write("project-root.jam", """ -import standalone ; +t.write("jamroot.jam", """ +import standalone ; """) -t.write("standalone.jam", """ +t.write("standalone.jam", """ import project ; project.initialize $(__name__) ; @@ -33,14 +30,13 @@ local pwd = [ PWD ] ; alias x : $(pwd)/../a.cpp ; alias runtime : x ; - """) -t.write("sub/Jamfile", """ -stage bin : /standalone//runtime ; +t.write("sub/jamfile.jam", """ +stage bin : /standalone//runtime ; """) t.run_build_system(subdir="sub") t.expect_addition("sub/bin/a.cpp") -t.cleanup() +t.cleanup() diff --git a/v2/test/startup_v1.py b/v2/test/startup_v1.py index 3598c9351..14a286a70 100644 --- a/v2/test/startup_v1.py +++ b/v2/test/startup_v1.py @@ -1,27 +1,23 @@ #!/usr/bin/python -# Copyright 2002 Dave Abrahams -# Copyright 2003, 2004, 2005 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 2002 Dave Abrahams +# Copyright 2003, 2004, 2005 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) -from BoostBuild import Tester +import BoostBuild import os import re -def expect_substring(actual,expected): +def expect_substring(actual, expected): return actual.find(expected) != -1 -def match_re(actual,expected): - return re.match(expected,actual,re.DOTALL) != None +def match_re(actual, expected): + return re.match(expected, actual, re.DOTALL) != None -# Test the v1 startup behavior -t = Tester( - executable='bjam' - , match=match_re - , boost_build_path='' - , pass_toolset=0 - ) +# Test the v1 startup behavior. +t = BoostBuild.Tester(executable='bjam', match=match_re, boost_build_path='', + pass_toolset=0) t.set_tree('startup') @@ -29,71 +25,57 @@ t.set_tree('startup') # t.run_build_system( # status=1, stdout="You didn't set BOOST_ROOT", match = expect_substring) -t.run_build_system( - extra_args = '-sBOOST_ROOT=.', status=1 - , stdout=r'''Unable to load Boost\.Build: could not find "boost-build\.jam".''' - ) +t.run_build_system(extra_args='-sBOOST_ROOT=.', status=1, + stdout=r'''Unable to load Boost\.Build: could not find ''' + + r'''"boost-build\.jam".''') os.chdir('no-bootstrap1') -t.run_build_system( - extra_args = '-sBOOST_ROOT=.', status=1 - , stdout=r'''Unable to load Boost\.Build: could not find build system\.''' +t.run_build_system(extra_args='-sBOOST_ROOT=.', status=1, + stdout=r'''Unable to load Boost\.Build: could not find build system\.''' + r'''.*attempted to load the build system by invoking''' + r'''.*'boost-build ;'.*''' - + r'''but we were unable to find "bootstrap\.jam"''' - ) + + r'''but we were unable to find "bootstrap\.jam"''') # Descend to a subdirectory which /doesn't/ contain a boost-build.jam # file, and try again to test the crawl-up behavior. os.chdir('subdir') -t.run_build_system( - extra_args = '-sBOOST_ROOT=.', status=1 - , stdout=r'''Unable to load Boost\.Build: could not find build system\.''' +t.run_build_system(extra_args='-sBOOST_ROOT=.', status=1, + stdout=r'''Unable to load Boost\.Build: could not find build system\.''' + r'''.*attempted to load the build system by invoking''' + r'''.*'boost-build ;'.*''' - + r'''but we were unable to find "bootstrap\.jam"''' - ) + + r'''but we were unable to find "bootstrap\.jam"''') os.chdir('../../no-bootstrap2') -t.run_build_system( - extra_args = '-sBOOST_ROOT=.', status=1 - , stdout=r'''Unable to load Boost\.Build: could not find build system\.''' +t.run_build_system(extra_args='-sBOOST_ROOT=.', status=1, + stdout=r'''Unable to load Boost\.Build: could not find build system\.''' + r'''.*attempted to load the build system by invoking''' + r'''.*'boost-build \. ;'.*''' - + r'''but we were unable to find "bootstrap\.jam"''' - ) + + r'''but we were unable to find "bootstrap\.jam"''') os.chdir('../no-bootstrap3') -t.run_build_system( - extra_args = '-sBOOST_ROOT=.', status=1 - , stdout=r'''Unable to load Boost.Build +t.run_build_system(extra_args='-sBOOST_ROOT=.', status=1, + stdout=r'''Unable to load Boost.Build .*boost-build.jam" was found.* -However, it failed to call the "boost-build" rule''' - ) +However, it failed to call the "boost-build" rule''') # test bootstrapping based on BOOST_BUILD_PATH os.chdir('../bootstrap-env') -t.run_build_system( - extra_args = '-sBOOST_ROOT=../boost-root -sBOOST_BUILD_PATH=../boost-root/build' - , stdout = 'build system bootstrapped' - ) +t.run_build_system(extra_args='-sBOOST_ROOT=../boost-root ' + + '-sBOOST_BUILD_PATH=../boost-root/build', + stdout='build system bootstrapped') # test bootstrapping based on an explicit path in boost-build.jam os.chdir('../bootstrap-explicit') -t.run_build_system( - extra_args = '-sBOOST_ROOT=../boost-root' - , stdout = 'build system bootstrapped' - ) +t.run_build_system(extra_args='-sBOOST_ROOT=../boost-root', + stdout='build system bootstrapped') # test bootstrapping based on BOOST_ROOT os.chdir('../bootstrap-implicit') -t.run_build_system( - extra_args = '-sBOOST_ROOT=../boost-root' - , stdout = 'build system bootstrapped' - ) +t.run_build_system(extra_args='-sBOOST_ROOT=../boost-root', + stdout='build system bootstrapped') t.cleanup() diff --git a/v2/test/startup_v2.py b/v2/test/startup_v2.py index abffbb828..a4faf56de 100644 --- a/v2/test/startup_v2.py +++ b/v2/test/startup_v2.py @@ -1,23 +1,20 @@ #!/usr/bin/python -# Copyright 2002 Dave Abrahams -# Copyright 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 2002 Dave Abrahams +# Copyright 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) -from BoostBuild import Tester +import BoostBuild import os import re + def match_re(actual,expected): return re.match(expected,actual,re.DOTALL) != None -# Test the v1 startup behavior -t = Tester( - match= match_re - , boost_build_path='' - , pass_toolset=0 - ) +# Test the v1 startup behavior. +t = BoostBuild.Tester(match=match_re, boost_build_path='', pass_toolset=0) t.set_tree('startup') @@ -35,8 +32,8 @@ t.run_build_system( + r'''but we were unable to find "bootstrap\.jam"''' ) -# Descend to a subdirectory which /doesn't/ contain a boost-build.jam -# file, and try again to test the crawl-up behavior. +# Descend to a subdirectory which /doesn't/ contain a boost-build.jam file, and +# try again to test the crawl-up behavior. os.chdir('subdir') t.run_build_system( @@ -66,18 +63,17 @@ t.run_build_system( However, it failed to call the "boost-build" rule''' ) -# test bootstrapping based on BOOST_BUILD_PATH +# Test bootstrapping based on BOOST_BUILD_PATH. os.chdir('../bootstrap-env') t.run_build_system( extra_args = '-sBOOST_BUILD_PATH=../boost-root/build' , stdout = 'build system bootstrapped' ) -# test bootstrapping based on an explicit path in boost-build.jam +# Test bootstrapping based on an explicit path in boost-build.jam. os.chdir('../bootstrap-explicit') t.run_build_system( stdout = 'build system bootstrapped' ) t.cleanup() - diff --git a/v2/test/suffix.py b/v2/test/suffix.py index 38b8ad2a3..cb4ad1180 100644 --- a/v2/test/suffix.py +++ b/v2/test/suffix.py @@ -1,33 +1,32 @@ #!/usr/bin/python -# Copyright 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, 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) -from BoostBuild import Tester, List +import BoostBuild -t = Tester() +t = BoostBuild.Tester() -# Regression test: when staging V2 used to change suffixes on targets -# corresponding to real files. -t.write("Jamfile", """ +# Regression test: when staging V2 used to change suffixes on targets +# corresponding to real files. +t.write("jamfile.jam", """ import type : register ; register A : a1 a2 a3 ; - -stage a : a.a3 ; +stage a : a.a3 ; """) -t.write("project-root.jam", "") +t.write("jamroot.jam", "") t.write("a.a3", "") t.run_build_system() t.expect_addition("a/a.a3"); -# Regression test: we should be able to specify empty suffix for -# derived target type, even if base type has non-empty suffix. +# Regression test: we should be able to specify empty suffix for derived target +# type, even if base type has non-empty suffix. t.write("a.cpp", "") -t.write("suffixes.jam", """ +t.write("suffixes.jam", """ import type ; import generators ; import common ; @@ -46,19 +45,17 @@ actions second { $(TOUCH) $(<) } - """) -t.write("project-root.jam", """ -import suffixes ; +t.write("jamroot.jam", """ +import suffixes ; """) -t.write("Jamfile", """ -second a : a.cpp ; +t.write("jamfile.jam", """ +second a : a.cpp ; """) t.run_build_system() t.expect_addition("bin/$toolset/debug/a") - t.cleanup() diff --git a/v2/test/svn_tree.py b/v2/test/svn_tree.py index 1ce8cd2b1..74bceb7f5 100644 --- a/v2/test/svn_tree.py +++ b/v2/test/svn_tree.py @@ -16,8 +16,8 @@ # ###################################################################### -# This file was modified by Vladimir Prus to store modification times in -# tree nodes. +# This file was modified by Vladimir Prus to store modification times in tree +# nodes. import re import string @@ -26,7 +26,6 @@ import os import stat - #======================================================================== # ===> Overview of our Datastructures <=== @@ -498,7 +497,7 @@ def compare_trees(a, b, def dump_tree(n,indent=""): "Print out a nice representation of the tree's structure." - # Code partially stolen from Dave Beazley + # Code partially stolen from Dave Beazley. if n.children is None: tmp_children = [] else: @@ -509,12 +508,11 @@ def dump_tree(n,indent=""): else: print "%s%s" % (indent, n.name) - indent = indent.replace("-"," ") - indent = indent.replace("+"," ") + indent = indent.replace("-", " ") + indent = indent.replace("+", " ") for i in range(len(tmp_children)): c = tmp_children[i] - if i == len(tmp_children - )-1: + if i == len(tmp_children) - 1: dump_tree(c,indent + " +-- ") else: dump_tree(c,indent + " |-- ") diff --git a/v2/test/symlink.py b/v2/test/symlink.py index 92c06248f..d78e96c15 100644 --- a/v2/test/symlink.py +++ b/v2/test/symlink.py @@ -1,36 +1,41 @@ #!/usr/bin/python -# Copyright 2003 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) +# Copyright 2003 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) -# Test the 'symlink' rule +# Test the 'symlink' rule. -from BoostBuild import Tester, List import os -t = Tester() +import BoostBuild + if os.name != 'posix': - print "The symlink tests can be run on posix only" + print "The symlink tests can be run on posix only." + import sys sys.exit(1) -t.write("project-root.jam", "import gcc ;") -t.write("Jamfile", """ + +t = BoostBuild.Tester() + +t.write("jamroot.jam", "import gcc ;") + +t.write("jamfile.jam", """ exe hello : hello.cpp ; -symlink hello_release : hello/release ; +symlink hello_release : hello/release ; symlink hello_debug : hello/debug ; -symlink links/hello_release : hello/release ; +symlink links/hello_release : hello/release ; """) + t.write("hello.cpp", """ -int main() -{ - return 0; -} +int main() {} """) t.run_build_system() -t.expect_addition(List('hello_debug.exe hello_release.exe links/hello_release.exe')) - +t.expect_addition([ + 'hello_debug.exe', + 'hello_release.exe', + 'links/hello_release.exe']) t.cleanup() diff --git a/v2/test/tag.py b/v2/test/tag.py index d65bed340..aef31e808 100644 --- a/v2/test/tag.py +++ b/v2/test/tag.py @@ -1,9 +1,9 @@ #!/usr/bin/python -# Copyright (C) Pedro Ferreira 2003. 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) Pedro Ferreira 2003. 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. import BoostBuild @@ -20,21 +20,21 @@ def test_folder_with_dot_in_name(t): a dot in their name. """ - t.write("version-1.32.0/Jamroot.jam", """ + t.write("version-1.32.0/jamroot.jam", """ project test : requirements @$(__name__).tag ; rule tag ( name : type ? : property-set ) { # Do nothing, just make sure the rule is invoked OK. - ECHO "The tag rule was invoked" ; + ECHO "The tag rule has been invoked." ; } exe a : a.cpp ; """) - t.write("version-1.32.0/a.cpp", "int main() { return 0; }\n") + t.write("version-1.32.0/a.cpp", "int main() {}\n") t.run_build_system(subdir="version-1.32.0") t.expect_addition("version-1.32.0/bin/$toolset/debug/a.exe") - t.expect_output_line("The tag rule was invoked") + t.expect_output_line("The tag rule has been invoked.") ################################################################################ @@ -48,7 +48,7 @@ def test_tag_property(t): """Basic tag property test. """ - t.write("Jamroot.jam", """ + t.write("jamroot.jam", """ import virtual-target ; rule tag ( name : type ? : property-set ) @@ -78,11 +78,7 @@ stage c : a ; """) t.write("a.cpp", """ -int main() -{ - return 0; -} - +int main() {} #ifdef _MSC_VER __declspec (dllexport) void x () {} #endif diff --git a/v2/test/template.py b/v2/test/template.py index 289053db2..1fbef07b8 100644 --- a/v2/test/template.py +++ b/v2/test/template.py @@ -1,41 +1,42 @@ #!/usr/bin/python -# Copyright (C) FILL SOMETHING HERE 2006. -# 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) +# Copyright (C) FILL SOMETHING HERE 2006. +# 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) -# This file is template for Boost.Build tests. It creates a simple -# project that builds one exe from one source, and checks that the exe -# is really created. -from BoostBuild import Tester, List +# This file is template for Boost.Build tests. It creates a simple project that +# builds one exe from one source, and checks that the exe is really created. -# Create a temporary working directory -t = Tester() +import BoostBuild -# Create the needed files -t.write("Jamroot", """ + +# Create a temporary working directory. +t = BoostBuild.Tester() + +# Create the needed files. +t.write("jamroot.jam", """ exe hello : hello.cpp ; """) + t.write("hello.cpp", """ -int main() -{ - return 0; -} - -""") +int main() {} +""" +# Run the build. t.run_build_system() -# 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. +# First, create a list of three pathnames. +file_list = BoostBuild.List("bin/$toolset/debug/") * \ + BoostBuild.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) -# Remove temporary directories +# Remove temporary directories. t.cleanup() diff --git a/v2/test/test1.py b/v2/test/test1.py index 9253269a9..3cdc71d2d 100644 --- a/v2/test/test1.py +++ b/v2/test/test1.py @@ -8,8 +8,9 @@ import BoostBuild t = BoostBuild.Tester() -t.write("test.jam",""" -actions unbuilt { } unbuilt all ; +t.write("test.jam", """ +actions unbuilt { } +unbuilt all ; ECHO "Hi" ; """) diff --git a/v2/test/test2.py b/v2/test/test2.py index b982d4001..b5c9ba824 100644 --- a/v2/test/test2.py +++ b/v2/test/test2.py @@ -1,24 +1,25 @@ #!/usr/bin/python -# Copyright 2002, 2003 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 2002, 2003 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) -from BoostBuild import Tester, List -from time import sleep +import BoostBuild -t = Tester() +t = BoostBuild.Tester() t.set_tree("test2") -t.run_build_system("-sBOOST_BUILD_PATH=" + t.original_workdir + "/..") -file_list = 'bin/foo/$toolset/debug/runtime-link-dynamic/' * List("foo foo.o") +file_list = 'bin/foo/$toolset/debug/runtime-link-dynamic/' * \ + BoostBuild.List("foo foo.o") + +t.run_build_system("-sBOOST_BUILD_PATH=" + t.original_workdir + "/..") t.expect_addition(file_list) -t.write("foo.cpp", "int main(int, char**) { return 0; }\n") +t.write("foo.cpp", "int main() {}\n") t.run_build_system("-d2 -sBOOST_BUILD_PATH=" + t.original_workdir + "/..") t.expect_touch(file_list) -t.pass_test() +t.pass_test() diff --git a/v2/test/test2/Jamfile b/v2/test/test2/jamfile.jam similarity index 100% rename from v2/test/test2/Jamfile rename to v2/test/test2/jamfile.jam diff --git a/v2/test/test_all.py b/v2/test/test_all.py index 13e878498..04d0978d9 100644 --- a/v2/test/test_all.py +++ b/v2/test/test_all.py @@ -6,17 +6,16 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -import os, sys, string +import os +import sys +import string import BoostBuild -from BoostBuild import get_toolset -# clear environment for testing + +# Clear environment for testing. # -for s in ( - 'BOOST_ROOT','BOOST_BUILD_PATH','JAM_TOOLSET','BCCROOT', - 'MSVCDir','MSVC','MSVCNT','MINGW','watcom' - ): - +for s in ('BOOST_ROOT', 'BOOST_BUILD_PATH', 'JAM_TOOLSET', 'BCCROOT', 'MSVCDir', + 'MSVC', 'MSVCNT', 'MINGW', 'watcom' ): try: del os.environ[s] except: @@ -24,12 +23,13 @@ for s in ( BoostBuild.set_defer_annotations(1) + def run_tests(critical_tests, other_tests): """Runs first critical tests and then other_tests. Stops on first error, and write the name of failed test to - test_results.txt. Critical tests are run in the specified order, - other tests are run starting with the one that failed the last time. + test_results.txt. Critical tests are run in the specified order, other + tests are run starting with the one that failed the last time. """ last_failed = last_failed_test() other_tests = reorder_tests(other_tests, last_failed) @@ -50,17 +50,16 @@ def run_tests(critical_tests, other_tests): f.write(i) f.close() failures_count = failures_count + 1 - # Restore the current directory, which might be changed by the - # test + # Restore the current directory, which might be changed by the test. os.chdir(invocation_dir) BoostBuild.flush_annotations(); continue print "PASSED" BoostBuild.flush_annotations(); pass_count = pass_count + 1 - sys.stdout.flush() # makes testing under emacs more entertaining. + sys.stdout.flush() # Makes testing under emacs more entertaining. - # Erase the file on success + # Erase the file on success. if failures_count == 0: open('test_results.txt', 'w') @@ -80,6 +79,7 @@ def last_failed_test(): except: return None + def reorder_tests(tests, first_test): try: n = tests.index(first_test) @@ -93,106 +93,110 @@ critical_tests = ["unit_tests", "module_actions", "startup_v1", "startup_v2"] critical_tests += ["core_d12", "core_typecheck", "core_delete_module", "core_varnames", "core_import_module"] -tests = [ "rebuilds", - "timedata", - "project_test3", - "project_test4", - "generators_test", - "dependency_test", - "path_features", - "relative_sources", - "no_type", +tests = [ "absolute_sources", + "alias", + "alternatives", + "bad_dirname", + "build_dir", + "build_file", + "build_no", + "c_file", "chain", - "default_build", - "default_toolset", - "use_requirements", + "clean", + "composite", "conditionals", "conditionals2", "conditionals3", "conditionals_multiple", "configuration", - "indirect_conditional", - "stage", - "prebuilt", - "project_dependencies", - "build_dir", - "searched_lib", - "make_rule", - "alias", - "alternatives", - "default_features", - "print", - "ndebug", - "explicit", - "absolute_sources", - "dependency_property", "custom_generator", - "bad_dirname", - "c_file", - "inline", - "property_expansion", - "loop", - "tag", - "suffix", - "inherit_toolset", - "skipping", - "project_glob", - "project_root_constants", - "double_loading", - "dll_path", - "regression", - "composite", - "library_chain", - "unit_test", - "standalone", - "expansion", - "wrapper", - "duplicate", - "library_property", - "load_order", - "wrong_project", - "using", - "source_locations", - "out_of_tree", - "notfile", - "project_root_rule", - "resolution", - "build_file", - "build_no", + "default_build", + "default_features", + "default_toolset", + "dependency_property", + "dependency_test", "disambiguation", - "clean", - "lib_source_property", - "implicit_dependency", + "dll_path", + "double_loading", + "duplicate", "example_libraries", "example_make", - "remove_requirement", - "free_features_request", + "expansion", + "explicit", "file_name_handling", - "sort_rule" + "free_features_request", + "generator_selection", + "generators_test", + "implicit_dependency", + "indirect_conditional", + "inherit_toolset", + "inherited_dependency", + "inline", + "lib_source_property", + "library_chain", + "library_property", + "load_order", + "loop", + "make_rule", + "ndebug", + "no_type", + "notfile", + "ordered_include", + "out_of_tree", + "path_features", + "prebuilt", + "print", + "project_dependencies", + "project_glob", + "project_root_constants", + "project_root_rule", + "project_test3", + "project_test4", + "property_expansion", + "rebuilds", + "regression", + "relative_sources", + "remove_requirement", + "resolution", + "searched_lib", + "skipping", + "sort_rule", + "source_locations", + "stage", + "standalone", + "suffix", + "tag", + "test_result_dumping", + "testing_support", + "timedata", + "unit_test", + "use_requirements", + "using", + "wrapper", + "wrong_project" ] if os.name == 'posix': tests.append("symlink") - # On windows, library order is not important, so skip this test - # Besides, it fails ;-) - # Further, the test relies on the fact that on Linux, one - # can build a shared library with unresolved symbols. This is - # not true on Windows (even with cygwin gcc). + # On windows, library order is not important, so skip this test. Besides, it + # fails ;-). Further, the test relies on the fact that on Linux, one can + # build a shared library with unresolved symbols. This is not true on + # Windows (even with cygwin gcc). if string.find(os.uname()[0], "CYGWIN") == -1: tests.append("library_order") -if string.find(get_toolset(), 'gcc') == 0: +if string.find(BoostBuild.get_toolset(), 'gcc') == 0: tests.append("gcc_runtime") -if string.find(get_toolset(), 'gcc') == 0 or string.find(get_toolset(), 'msvc') == 0: +if ( string.find(BoostBuild.get_toolset(), 'gcc') == 0 )or \ + ( string.find(BoostBuild.get_toolset(), 'msvc') == 0 ): tests.append("pch") 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. + # Requires ./whatever.py to work, so is not guaranted to work everywhere. tests.append("example_customization") # Requires gettext tools. tests.append("example_gettext") diff --git a/v2/test/test_result_dumping.py b/v2/test/test_result_dumping.py new file mode 100755 index 000000000..07eb59480 --- /dev/null +++ b/v2/test/test_result_dumping.py @@ -0,0 +1,33 @@ +#!/usr/bin/python + +# 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) + +# Tests dumping Boost Build based testing results. + +import BoostBuild + + +################################################################################ +# +# Test that dumping Boost Build based testing results works in case test code +# is not located in a folder under the Jamroot folder. +# +################################################################################ + +t = BoostBuild.Tester("--dump-tests") + +t.write("TestBuild/jamroot.jam", """ +import testing ; +test-suite testit : [ run ../TestSource/test.cpp ] ; +""") + +t.write("TestSource/test.cpp", """ +int main() {} +""") + +t.run_build_system("", subdir="TestBuild") +t.expect_output_line('boost-test(RUN) "*/TestBuild/test" : "../TestSource/test.cpp"') + +t.cleanup() diff --git a/v2/test/test_system.html b/v2/test/test_system.html index 876c682d2..32ff363d2 100644 --- a/v2/test/test_system.html +++ b/v2/test/test_system.html @@ -112,12 +112,11 @@ "../../../jam/index.html">$boost_build_root/jam/index.html for instructions.
  • -
  • Configure at least one toolset. You can edit - site-config.jam or user-config.jam to add new - toolsets. Or you can create file test-config.jam in - $boost_build_root/test directory. In this case, - site-config.jam and user-config.jam will be ignored - for testing.
  • +
  • Configure at least one toolset. You can edit site-config.jam + or user-config.jam to add new toolsets. Or you can create file + test-config.jam in $boost_build_root/test directory. In + this case, site-config.jam and user-config.jam will be + ignored for testing.
  • When all is set, you can run all the tests using the test_all.py @@ -211,14 +210,14 @@ python generators_test.py msvc-7.1

    The "hello.py" module might contain:

    -from BoostBuild import Tester, List
    +from BoostBuild import List
     
     # Create a temporary working directory
    -t = Tester()
    +t = BoostBuild.Tester()
     
     # Create the needed files
    -t.write("project-root.jam", "")
    -t.write("Jamfile", """
    +t.write("jamroot.jam", "")
    +t.write("jamfile.jam", """
     exe hello : hello.cpp ;
     """)
     t.write("hello.cpp", """
    diff --git a/v2/test/testing_primitives.py b/v2/test/testing_primitives.py
    index b2607390b..ae62993b3 100644
    --- a/v2/test/testing_primitives.py
    +++ b/v2/test/testing_primitives.py
    @@ -4,34 +4,27 @@
     # 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) 
     
    -from BoostBuild import Tester, List
    -import os
    -from string import strip
    +import BoostBuild
     import re
     
    -def match_re(actual,expected):
    -    return re.match(expected,actual,re.DOTALL) != None
    +def match_re(actual, expected):
    +    return re.match(expected, actual, re.DOTALL) != None
     
    -t = Tester(match = match_re)
    +t = BoostBuild.Tester(match=match_re)
     
     t.set_tree('testing-primitives')
     
    -# We expect t5 and t7's output to be dumped to stdout
    +# We expect t5 and t7's output to be dumped to stdout.
     t.run_build_system(stdout=r'''.*failing t5.*failing t7''')
     
     t.expect_addition('t2.txt')
     t.expect_addition('t3.txt')
    -
     t.expect_addition('t5.out')
    -
     t.expect_addition('t6.out')
     t.expect_addition('t6.txt')
    -
     t.expect_addition('t7.out')
     t.expect_addition('t7.txt')
    -
     t.expect_addition('t8.out')
    -
     t.expect_nothing_more()
    +
     t.cleanup()
    -print 'tesing complete'
    diff --git a/v2/test/testing_support.py b/v2/test/testing_support.py
    new file mode 100755
    index 000000000..eee4345c5
    --- /dev/null
    +++ b/v2/test/testing_support.py
    @@ -0,0 +1,61 @@
    +#!/usr/bin/python
    +
    +# 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)
    +
    +# Tests different aspects of Boost Builds automated testing support.
    +
    +import BoostBuild
    +
    +
    +################################################################################
    +#
    +# test_files_with_spaces_in_their_name()
    +# --------------------------------------
    +#
    +################################################################################
    +
    +def test_files_with_spaces_in_their_name():
    +    """Regression test making sure test result files get created correctly when
    +    testing files with spaces in their name.
    +    """
    +
    +    t = BoostBuild.Tester()
    +
    +    t.write("valid source.cpp", "int main() {}\n");
    +
    +    t.write("invalid source.cpp", "this is not valid source code");
    +    
    +    t.write("jamroot.jam", """
    +import testing ;
    +testing.compile "valid source.cpp" ;
    +testing.compile-fail "invalid source.cpp" ;
    +""")
    +
    +    t.run_build_system(status=0)
    +    t.expect_addition("bin/invalid source.test/$toolset/debug/invalid source.obj")
    +    t.expect_addition("bin/invalid source.test/$toolset/debug/invalid source.test")
    +    t.expect_addition("bin/valid source.test/$toolset/debug/valid source.obj")
    +    t.expect_addition("bin/valid source.test/$toolset/debug/valid source.test")
    +
    +    t.expect_content("bin/valid source.test/$toolset/debug/valid source.test", \
    +        "passed" )
    +    t.expect_content( \
    +        "bin/invalid source.test/$toolset/debug/invalid source.test", \
    +        "passed" )
    +    t.expect_content( \
    +        "bin/invalid source.test/$toolset/debug/invalid source.obj", \
    +        "failed as expected" )
    +
    +    t.cleanup()
    +
    +
    +################################################################################
    +#
    +# main()
    +# ------
    +#
    +################################################################################
    +
    +test_files_with_spaces_in_their_name()
    diff --git a/v2/test/timedata.py b/v2/test/timedata.py
    index 8a3d87c76..04ec99f98 100644
    --- a/v2/test/timedata.py
    +++ b/v2/test/timedata.py
    @@ -1,16 +1,30 @@
     #!/usr/bin/python
    -# Copyright David Abrahams 2005. 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)
     
    -# This tests the build step timing facilities.
    +# Copyright 2005 David Abrahams
    +# 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)
    +
    +# Tests the build step timing facilities.
    +
     
     import BoostBuild
     import re
     
    -t = BoostBuild.Tester(pass_toolset=0)
     
    -t.write("file.jam", """
    +################################################################################
    +#
    +# basic_jam_action_test()
    +# -----------------------
    +#
    +################################################################################
    +
    +def basic_jam_action_test():
    +    """Tests basic Jam action timing support."""
    +
    +    t = BoostBuild.Tester(pass_toolset=0)
    +
    +    t.write("file.jam", """
     rule time
     {
         DEPENDS $(<) : $(>) ;
    @@ -40,14 +54,13 @@ actions make
         echo made from $(>) >> $(<)
     }
     
    -
     time foo : bar ;
     make bar : baz ;
     """)
     
    -t.write("baz", "nothing\n")
    +    t.write("baz", "nothing\n")
     
    -expected_output = """\.\.\.found 4 targets\.\.\.
    +    expected_output = """\.\.\.found 4 targets\.\.\.
     \.\.\.updating 2 targets\.\.\.
     make bar
     time foo
    @@ -55,10 +68,88 @@ bar +user: [0-9\.]+ +system: +[0-9\.]+ *
     \.\.\.updated 2 targets\.\.\.$
     """
     
    -t.run_build_system("-ffile.jam -d+1", stdout=expected_output,
    -    match=lambda actual, expected: re.search(expected, actual, re.DOTALL))
    -t.expect_addition("foo")
    -t.expect_addition("bar")
    -t.expect_nothing_more()
    +    t.run_build_system("-ffile.jam -d+1", stdout=expected_output, match=lambda
    +        actual, expected: re.search(expected, actual, re.DOTALL))
    +    t.expect_addition("foo")
    +    t.expect_addition("bar")
    +    t.expect_nothing_more()
     
    -t.cleanup()
    +    t.cleanup()
    +
    +
    +################################################################################
    +#
    +# boost_build_testing_support_timing_rule():
    +# ------------------------------------------
    +#
    +################################################################################
    +
    +def boost_build_testing_support_timing_rule():
    +    """Tests the target build timing rule provided by the Boost Build testing
    +    support system.
    +    """
    +
    +    t = BoostBuild.Tester()
    +
    +    t.write("aaa.cpp", "int main() {}\n")
    +
    +    t.write("jamroot.jam", """
    +import testing ;
    +exe my-exe : aaa.cpp ;
    +time my-time : my-exe ;
    +""")
    +
    +    t.run_build_system()
    +    t.expect_addition("bin/$toolset/debug/aaa.obj")
    +    t.expect_addition("bin/$toolset/debug/my-exe.exe")
    +    t.expect_addition("bin/$toolset/debug/my-time.time")
    +
    +    t.expect_content_line("bin/$toolset/debug/my-time.time", "user: *")
    +    t.expect_content_line("bin/$toolset/debug/my-time.time", "system: *")
    +
    +    t.cleanup()
    +
    +
    +################################################################################
    +#
    +# boost_build_testing_support_timing_rule_with_spaces_in_names()
    +# --------------------------------------------------------------
    +#
    +################################################################################
    +
    +def boost_build_testing_support_timing_rule_with_spaces_in_names():
    +    """Tests the target build timing rule provided by the Boost Build testing
    +    support system when used with targets contining spaces in their names.
    +    """
    +
    +    t = BoostBuild.Tester()
    +
    +    t.write("aaa bbb.cpp", "int main() {}\n")
    +
    +    t.write("jamroot.jam", """
    +import testing ;
    +exe "my exe" : "aaa bbb.cpp" ;
    +time "my time" : "my exe" ;
    +""")
    +
    +    t.run_build_system()
    +    t.expect_addition("bin/$toolset/debug/aaa bbb.obj")
    +    t.expect_addition("bin/$toolset/debug/my exe.exe")
    +    t.expect_addition("bin/$toolset/debug/my time.time")
    +
    +    t.expect_content_line("bin/$toolset/debug/my time.time", "user: *")
    +    t.expect_content_line("bin/$toolset/debug/my time.time", "system: *")
    +
    +    t.cleanup()
    +
    +
    +################################################################################
    +#
    +# main()
    +# ------
    +#
    +################################################################################
    +
    +basic_jam_action_test()
    +boost_build_testing_support_timing_rule()
    +boost_build_testing_support_timing_rule_with_spaces_in_names()
    \ No newline at end of file
    diff --git a/v2/test/tree.py b/v2/test/tree.py
    index af2ff25e5..89f8ad4ff 100644
    --- a/v2/test/tree.py
    +++ b/v2/test/tree.py
    @@ -1,7 +1,7 @@
    -# Copyright 2003 Dave Abrahams 
    -# Copyright 2001, 2002 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 2001, 2002 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 based in part on the content of svn_tree.py.
     
    @@ -20,7 +20,7 @@ class Trees_difference:
             self.removed_files.extend(other.removed_files)
             self.modified_files.extend(other.modified_files)
             self.touched_files.extend(other.touched_files)
    -     
    +
         def ignore_directories(self):
             "Removes directories for list of found differences"
     
    @@ -33,13 +33,15 @@ class Trees_difference:
     
         def pprint(self, f=None):
             print >> f, "Added files   :", self.added_files
    -        print >> f,"Removed files :", self.removed_files
    +        print >> f, "Removed files :", self.removed_files
             print >> f, "Modified files:", self.modified_files
             print >> f, "Touched files :", self.touched_files
     
         def empty(self):
    -        return (len(self.added_files) == 0 and len(self.removed_files) == 0)\
    -                and len(self.modified_files) == 0 and len(self.touched_files) == 0
    +        return ( len(self.added_files) == 0 ) and \
    +            ( len(self.removed_files) == 0 ) and \
    +            ( len(self.modified_files) == 0 ) and \
    +            ( len(self.touched_files) == 0 )
     
     def build_tree(dir):
         return svn_tree.build_tree_from_wc(dir, load_props=0, ignore_svn=1)
    diff --git a/v2/test/unit_test.py b/v2/test/unit_test.py
    index f3ec569ec..94575ad31 100644
    --- a/v2/test/unit_test.py
    +++ b/v2/test/unit_test.py
    @@ -1,16 +1,17 @@
     #!/usr/bin/python
     
    -# Copyright 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, 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)
    +
    +#  Test the unit_test rule.
     
    -#  Test the unit_test rule
     import BoostBuild
     
     t = BoostBuild.Tester()
     
     # Create the needed files.
    -t.write("Jamroot.jam", """
    +t.write("jamroot.jam", """
     using testing ;
     lib helper : helper.cpp ;
     unit-test test : test.cpp : helper ;
    @@ -18,11 +19,7 @@ unit-test test : test.cpp : helper ;
     
     t.write("test.cpp", """
     void helper();
    -int main()
    -{
    -    helper();
    -    return 0;
    -}
    +int main() { helper(); }
     """)
     
     t.write("helper.cpp", """
    diff --git a/v2/test/unit_tests.py b/v2/test/unit_tests.py
    index 7da89f609..b2cac4bd5 100644
    --- a/v2/test/unit_tests.py
    +++ b/v2/test/unit_tests.py
    @@ -4,9 +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) 
     
    -from BoostBuild import Tester
    +import BoostBuild
    +
    +t = BoostBuild.Tester(pass_toolset=0)
     
    -t = Tester(pass_toolset=0)
     t.run_build_system(extra_args="--debug --build-system=test")
     
     t.cleanup()
    diff --git a/v2/test/unused.py b/v2/test/unused.py
    index 976efed89..9db2380cd 100644
    --- a/v2/test/unused.py
    +++ b/v2/test/unused.py
    @@ -6,26 +6,26 @@
     
     # Test that unused sources are at least reported.
     
    -from BoostBuild import Tester
    +import BoostBuild
     from string import find
    -t = Tester()
    +
    +t = BoostBuild.Tester()
     
     t.set_tree("unused")
     
     t.run_build_system()
    -# The second invocation should do nothing, and produce
    -# no warning. The previous invocation might have printed
    -# executed actions and other things, so it's not easy
    -# to check if warning was issued or not.
    +# The second invocation should do nothing, and produce no warning. The previous
    +# invocation might have printed executed actions and other things, so it is not
    +# easy to check if warning was issued or not.
     t.run_build_system()
     t.fail_test(find(t.stdout(), "warning: Unused source { b.X } in main target ./a") == -1)
     
     t.run_build_system("-sGENERATE_ONLY_UNUSABLE=1")
     t.fail_test(find(t.stdout(), "warning: Unused source { b.X } in main target ./a") == -1)
     
    -# Now check that even if main target generates nothing, its
    -# usage requirements are still propagated to dependents.
    -t.write("a.cpp","""
    +# Now check that even if main target generates nothing, its usage requirements
    +# are still propagated to dependants.
    +t.write("a.cpp", """
     #ifdef FOO
     int main() {}
     #endif
    @@ -33,4 +33,3 @@ int main() {}
     t.run_build_system("-sGENERATE_NOTHING=1")
     
     t.cleanup()
    -
    diff --git a/v2/test/unused/Jamfile b/v2/test/unused/jamfile.jam
    similarity index 100%
    rename from v2/test/unused/Jamfile
    rename to v2/test/unused/jamfile.jam
    diff --git a/v2/test/unused/project-root.jam b/v2/test/unused/jamroot.jam
    similarity index 100%
    rename from v2/test/unused/project-root.jam
    rename to v2/test/unused/jamroot.jam
    diff --git a/v2/test/use_requirements.py b/v2/test/use_requirements.py
    index 546abde54..a73c01f1f 100644
    --- a/v2/test/use_requirements.py
    +++ b/v2/test/use_requirements.py
    @@ -1,33 +1,29 @@
     #!/usr/bin/python
     
    -# Copyright 2003 Dave Abrahams 
    -# Copyright 2002, 2003, 2004, 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 2002, 2003, 2004, 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)
     
    -from BoostBuild import Tester
    -t = Tester()
    +import BoostBuild
     
    -# Test that use requirements on main target work
    -# (and a propagated all the way up, not only to direct
    -# dependents)
    -t.write("project-root.jam", "import gcc ;")
    +t = BoostBuild.Tester()
     
    -# Note: 'lib cc ..', not 'lib c', If using 'lib c: ...' the HP-CXX
    -# linker will confuse it with the system C runtime.
    -t.write(
    -    "Jamfile",
    -"""
    -    lib b : b.cpp : shared:SHARED_B
    -    : : FOO shared:SHARED_B    
    -    ;
    -    lib cc : c.cpp b ;
    -    exe a : a.cpp cc ;
    +
    +# Test that use requirements on main target work (and a propagated all the way
    +# up, not only to direct dependants).
    +t.write("jamroot.jam", "import gcc ;")
    +
    +# Note: 'lib cc ..', not 'lib c'. If using 'lib c: ...' the HP-CXX linker will
    +# confuse it with the system C runtime.
    +t.write("jamfile.jam", """
    +lib b : b.cpp : shared:SHARED_B : :
    +    FOO shared:SHARED_B ;
    +lib cc : c.cpp b ;
    +exe a : a.cpp cc ;
     """)
     
    -t.write(
    -    "b.cpp",
    -"""
    +t.write("b.cpp", """
     void
     #if defined(_WIN32) && defined(SHARED_B)
     __declspec(dllexport)
    @@ -35,9 +31,7 @@ __declspec(dllexport)
     foo() {}\n
     """)
     
    -t.write(
    -    "c.cpp",
    -"""
    +t.write("c.cpp", """
     void
     #if defined(_WIN32) && defined(SHARED_B)
     __declspec(dllexport)
    @@ -45,10 +39,7 @@ __declspec(dllexport)
     create_lib_please() {}\n
     """)
     
    -
    -t.write(
    -    "a.cpp",
    -"""
    +t.write("a.cpp", """
     #ifdef FOO
     void
     # if defined(_WIN32) && defined(SHARED_B)
    @@ -56,30 +47,24 @@ __declspec(dllexport)
     # endif
     foo() {}
     #endif
    -
     int main() { foo(); }
     """)
     
     t.run_build_system()
    -
     t.run_build_system("--clean")
     
    +
     # Test that use requirements on main target work, when they are referred using
     # 'dependency' features.
    -t.write("project-root.jam", "import gcc ;")
    +t.write("jamroot.jam", "import gcc ;")
     
    -t.write(
    -    "Jamfile", 
    -"""
    -    lib b : b.cpp : shared:SHARED_B
    -    : : FOO shared:SHARED_B
    -    ;
    -    exe a : a.cpp : b ;
    +t.write("jamfile.jam", """
    +lib b : b.cpp : shared:SHARED_B : : FOO
    +    shared:SHARED_B ;
    +exe a : a.cpp : b ;
     """)
     
    -t.write(
    -    "b.cpp",
    -"""
    +t.write("b.cpp", """
     void
     #if defined(_WIN32) && defined(SHARED_B)
     __declspec(dllexport)
    @@ -87,11 +72,9 @@ __declspec(dllexport)
     foo() {}
     """)
     
    -t.write(
    -    "a.cpp",
    -"""
    +t.write("a.cpp", """
     #ifdef FOO
    -int main() { return 0; }
    +int main() {}
     #endif
     """)
     
    @@ -100,22 +83,17 @@ t.run_build_system()
     t.run_build_system("--clean")
     
     
    -# Test that use requirement on project work
    -t.write("Jamfile", "exe a : a.cpp lib//b ;")
    +# Test that usage requirements on a project work.
    +t.write("jamfile.jam", "exe a : a.cpp lib//b ;")
     
    -t.write(
    -    "lib/Jamfile", 
    -"""
    +t.write("lib/jamfile.jam", """
     project
        : requirements shared:SHARED_B
    -   : usage-requirements FOO shared:SHARED_B
    -    ;
    +   : usage-requirements FOO shared:SHARED_B ;
     lib b : b.cpp ;
     """)
     
    -t.write(
    -    "lib/b.cpp", 
    -"""
    +t.write("lib/b.cpp", """
     void
     #if defined(_WIN32) && defined(SHARED_B)
     __declspec(dllexport)
    @@ -125,42 +103,29 @@ foo() {}\n
     
     t.run_build_system()
     
    -# Test that use requirements are inherited correctly
     
    -t.write("Jamfile", "exe a : a.cpp lib/1//b ;")
    +# Test that use requirements are inherited correctly.
    +t.write("jamfile.jam", "exe a : a.cpp lib/1//b ;")
     
    -t.write(
    -    "a.cpp", 
    -"""
    +t.write("a.cpp", """
     #if defined(FOO) && defined(ZOO)
     void foo() {}
     #endif
    -
     int main() { foo(); }
     """)
     
    -t.write(
    -    "lib/Jamfile", 
    -"""
    -project
    -   : requirements
    -   : usage-requirements FOO
    -    ;
    +t.write("lib/jamfile.jam", """
    +project : requirements : usage-requirements FOO ;
     """)
     
    -t.write(
    -    "lib/1/Jamfile", 
    -"""
    +t.write("lib/1/jamfile.jam", """
     project
        : requirements shared:SHARED_B
    -   : usage-requirements ZOO shared:SHARED_B 
    -   ;
    +   : usage-requirements ZOO shared:SHARED_B ;
     lib b : b.cpp ;
     """)
     
    -t.write(
    -    "lib/1/b.cpp", 
    -"""
    +t.write("lib/1/b.cpp", """
     void
     #if defined(_WIN32) && defined(SHARED_B)
     __declspec(dllexport)
    @@ -171,29 +136,22 @@ foo() {}\n
     t.run_build_system()
     t.run_build_system("--clean")
     
    -# Test that we correctly handle dependency features
    -# in use requirements on target
     
    -t.write(
    -    "Jamfile", 
    -"""
    -    lib b : b.cpp : shared:SHARED_B 
    -    : : FOO shared:SHARED_B
    -    ;
    -    
    -    # Here's the test: we should correctly
    -    # handle dependency feature and get
    -    # use requirements from 'b'.
    -    lib cc : c.cpp : shared:SHARED_C : : b ;
    -    
    -    # This will build only if FOO
    -    # was propagated from 'c'.
    -    exe a : a.cpp cc ;
    +# Test that we correctly handle dependency features in use requirements on
    +# target.
    +t.write("jamfile.jam", """
    +lib b : b.cpp : shared:SHARED_B : : FOO
    +    shared:SHARED_B ;
    +
    +# Here's the test: we should correctly handle dependency feature and get usage
    +# requirements from 'b'.
    +lib cc : c.cpp : shared:SHARED_C : : b ;
    +
    +# This will build only if FOO was propagated from 'c'.
    +exe a : a.cpp cc ;
     """)
     
    -t.write(
    -    "a.cpp", 
    -"""
    +t.write("a.cpp", """
     #ifdef FOO
     void
     # if defined(_WIN32) && defined(SHARED_B)
    @@ -205,10 +163,8 @@ foo();
     int main() { foo(); }
     """)
     
    -t.write(
    -    "c.cpp",
    -"""
    -int 
    +t.write("c.cpp", """
    +int
     #if defined(_WIN32) && defined(SHARED_C)
     __declspec(dllexport)
     #endif
    @@ -218,119 +174,97 @@ must_export_something;
     t.run_build_system()
     t.run_build_system("--clean")
     
    -# Test correct handling of dependency features in 
    -# project requirements.
    -t.write(
    -    "Jamfile",
    -"""
    -    exe a : a.cpp lib1//cc ;
    +
    +# Test correct handling of dependency features in project requirements.
    +t.write("jamfile.jam", """
    +exe a : a.cpp lib1//cc ;
     """)
     
    -t.write(
    -    "lib1/Jamfile",
    -"""
    -    project
    +t.write("lib1/jamfile.jam", """
    +project
         : requirements shared:SHARED_C
    -    : usage-requirements ../lib2//b shared:SHARED_C
    -    ;
    -    
    -    lib cc : c.cpp ;    
    +    : usage-requirements ../lib2//b shared:SHARED_C ;
    +lib cc : c.cpp ;
     """)
     
    -t.write(
    -    "lib1/c.cpp", 
    -"""
    -int 
    +t.write("lib1/c.cpp", """
    +int
     #if defined(_WIN32) && defined(SHARED_C)
     __declspec(dllexport)
     #endif
     must_export_something;
     """)
     
    -t.write(
    -    "lib2/Jamfile", 
    -"""
    -    lib b : b.cpp : shared:SHARED_B
    -    : : FOO shared:SHARED_B ;
    +t.write("lib2/jamfile.jam", """
    +lib b : b.cpp : shared:SHARED_B : : FOO
    +    shared:SHARED_B ;
     """)
     
     t.copy("b.cpp", "lib2/b.cpp")
     
     t.run_build_system()
     
    -# Test that dependency feature in use requirements are built
    -# with the correct properties
    +
    +# Test that dependency feature in use requirements are built with the correct
    +# properties.
     t.rm(".")
     
    -t.write(
    -    "Jamfile", 
    -""" 
    -lib main : main.cpp : libs//lib1 : : libs//lib1 ; 
    +t.write("jamfile.jam", """
    +lib main : main.cpp : libs//lib1 : : libs//lib1 ;
     exe hello : hello.cpp main : ;
     """)
     
    -t.write(
    -    "main.cpp", 
    -""" 
    +t.write("main.cpp", """
     void
     #if defined(_WIN32) && defined(SHARED_LIB1)
     __declspec(dllimport)
     #endif
     foo();
     
    -int main() { foo(); return 0; } 
    +int main() { foo(); }
     """)
     
     t.write("hello.cpp", "\n")
     
    -t.write(
    -    "project-root.jam",
    -""" 
    -import gcc ; 
    +t.write("jamroot.jam", """
    +import gcc ;
     """)
     
    -t.write(
    -    "libs/a.cpp", 
    -""" 
    +t.write("libs/a.cpp", """
     void
     #if defined(_WIN32) && defined(SHARED_LIB1)
     __declspec(dllexport)
     #endif
    -foo() {} 
    +foo() {}
     """)
     
    -# This library should be build with the same properties as
    -# 'main'. There were a bug when they were generated with 
    -# empty properties, and there were ambiguity between variants.
    -t.write(
    -    "libs/Jamfile", 
    -""" 
    -lib lib1 : a_d.cpp : debug shared:SHARED_LIB1
    -: : shared:SHARED_LIB1 ;
     
    -lib lib1 : a.cpp : release shared:SHARED_LIB1
    -: : shared:SHARED_LIB1 ; 
    +# This library should be build with the same properties as 'main'. This is a
    +# regression test for a bug when they were generated with empty properties, and
    +# there were ambiguity between variants.
    +t.write("libs/jamfile.jam", """
    +lib lib1 : a_d.cpp : debug shared:SHARED_LIB1 : :
    +    shared:SHARED_LIB1 ;
    +lib lib1 : a.cpp : release shared:SHARED_LIB1 : :
    +    shared:SHARED_LIB1 ;
     """)
     
    -t.write(
    -    "libs/a_d.cpp", 
    -""" 
    +t.write("libs/a_d.cpp", """
     void
     #if defined(_WIN32) && defined(SHARED_LIB1)
     __declspec(dllexport)
     #endif
    -foo() {} 
    +foo() {}
     """)
     
     t.run_build_system("link=static")
     t.expect_addition("libs/bin/$toolset/debug/link-static/a_d.obj")
     
     
    -# Test that indirect conditionals are respected in
    -# usage requirements.
    +# Test that indirect conditionals are respected in usage requirements.
     t.rm(".")
     
    -t.write("Jamroot", """
    +t.write("jamroot.jam", """
     rule has-foo ( properties * )
     {
         return HAS_FOO ;
    @@ -339,12 +273,14 @@ rule has-foo ( properties * )
     exe a : a.cpp b ;
     lib b : b.cpp : static : : @has-foo ;
     """)
    +
     t.write("a.cpp", """
     #ifdef HAS_FOO
     void foo();
     int main() { foo(); }
     #endif
     """)
    +
     t.write("b.cpp", """
     void
     #if defined(_WIN32) && defined(SHARED_B)
    @@ -352,8 +288,8 @@ __declspec(dllexport)
     #endif
     foo() {}\n
     """)
    +
     t.run_build_system()
     t.expect_addition("bin/$toolset/debug/a.exe")
     
    -
     t.cleanup()
    diff --git a/v2/test/using.py b/v2/test/using.py
    index f616d4494..4e47f5f7f 100644
    --- a/v2/test/using.py
    +++ b/v2/test/using.py
    @@ -1,43 +1,33 @@
     #!/usr/bin/python
     
    -#  Copyright (C) Vladimir Prus 2005.
    -#  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)
    +# Copyright (C) Vladimir Prus 2005.
    +# 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)
     
    -from BoostBuild import Tester, List
    -import string
    +import BoostBuild
     
    -t = Tester()
    -
    -t.write("sub/a.cpp", """ 
    -int main() { return 0; }
    +t = BoostBuild.Tester()
     
    +t.write("sub/a.cpp", """
    +int main() {}
     """)
     
    -t.write("Jamroot", """ 
    +t.write("jamroot.jam", """
     using some_tool ;
     """)
     
    -t.write("some_tool.jam", """ 
    +t.write("some_tool.jam", """
     import project ;
     project.initialize $(__name__) ;
    -
    -rule init ( )
    -{
    -}
    -
    +rule init ( ) { }
     """)
     
    -t.write("sub/Jamfile", """ 
    -exe a : a.cpp ; 
    +t.write("sub/jamfile.jam", """
    +exe a : a.cpp ;
     """)
     
    -
    -
     t.run_build_system(subdir="sub")
    -
     t.expect_addition("sub/bin/$toolset/debug/a.exe")
     
     t.cleanup()
    -
    diff --git a/v2/test/v1-testing/Jamfile b/v2/test/v1-testing/jamfile.jam
    similarity index 100%
    rename from v2/test/v1-testing/Jamfile
    rename to v2/test/v1-testing/jamfile.jam
    diff --git a/v2/test/v1_testing.py b/v2/test/v1_testing.py
    index b1de60fb1..524775fac 100644
    --- a/v2/test/v1_testing.py
    +++ b/v2/test/v1_testing.py
    @@ -1,11 +1,11 @@
     #!/usr/bin/python
     
    -# Copyright 2002 Dave Abrahams 
    -# Copyright 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 2002 Dave Abrahams
    +# Copyright 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)
     
    -from BoostBuild import Tester, List
    +import BoostBuild
     import os
     from string import strip
     import re
    @@ -14,7 +14,7 @@ import time
     def match_re(actual,expected):
         return re.match(expected,actual,re.DOTALL) != None
     
    -t = Tester(match = match_re, boost_build_path = os.path.join(os.getcwd(), ".."))
    +t = BoostBuild.Tester(match = match_re, boost_build_path = os.path.join(os.getcwd(), ".."))
     t.set_tree('v1_testing')
     
     os.environ['TOOLS'] = 'gcc'
    @@ -59,11 +59,11 @@ t.expect_addition(
          # function, but we actually need to spell out a lot more than
          # what we currently have to do that.
     
    -# 4) Introduced error into one of the library files, causing a library build 
    -# compile to fail. path_test.test was deleted, so the reporting programs 
    -# would know that failure occurred. Excellent! This is the case that has 
    -# caused regression testing to report the wrong results in the past, so it 
    -# was good news to see it working correctly now. We probably should figure 
    +# 4) Introduced error into one of the library files, causing a library build
    +# compile to fail. path_test.test was deleted, so the reporting programs
    +# would know that failure occurred. Excellent! This is the case that has
    +# caused regression testing to report the wrong results in the past, so it
    +# was good news to see it working correctly now. We probably should figure
     # out some other test cases just to be sure it is working for full coverage.
     t.rename('lib.cpp', 'lib.cpp.bak')
     t.rename('lib-err.cpp', 'lib.cpp')
    @@ -74,9 +74,9 @@ t.expect_removal(
          , 'bin/nolink.test/gcc/debug/runtime-link-dynamic/nolink.test'
          , 'bin/run.test/gcc/debug/runtime-link-dynamic/run.test'])
     
    -# 5) Fixed the error in the library file.  The library build then worked, and 
    -# path_test.exe was relinked, without first recompiling path_test.obj. Test 
    -# was rerun. Exactly right behavior!
    +# 5) Fixed the error in the library file.  The library build then worked, and
    +# path_test.exe was relinked, without first recompiling path_test.obj. Test was
    +# rerun. Exactly the right behavior!
     t.rename('lib.cpp.bak', 'lib.cpp')
     t.run_build_system(arguments = 'test', status = 0)
     t.expect_addition(
    @@ -85,4 +85,4 @@ t.expect_addition(
          , 'bin/run.test/gcc/debug/runtime-link-dynamic/run.test'])
     
     t.cleanup()
    -print 'tesing complete'
    +print 'testing complete'
    diff --git a/v2/test/v1_testing/Jamfile b/v2/test/v1_testing/jamfile.jam
    similarity index 100%
    rename from v2/test/v1_testing/Jamfile
    rename to v2/test/v1_testing/jamfile.jam
    diff --git a/v2/test/v1_testing/project-root.jam b/v2/test/v1_testing/jamroot.jam
    similarity index 100%
    rename from v2/test/v1_testing/project-root.jam
    rename to v2/test/v1_testing/jamroot.jam
    diff --git a/v2/test/wrapper.py b/v2/test/wrapper.py
    index 74e8516f0..676892fa9 100644
    --- a/v2/test/wrapper.py
    +++ b/v2/test/wrapper.py
    @@ -1,46 +1,38 @@
     #!/usr/bin/python
     
    -# Copyright 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 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)
     
    -#  Test that the user can define his own rule that will call builtin main
    -#  target rule and that this will work.
    +# Test that the user can define his own rule that will call built-in main target
    +# rule and that this will work.
     
    -from BoostBuild import Tester, List
    -
    -t = Tester()
    -
    -t.write("Jamfile", """ my-test : test.cpp ;
    +import BoostBuild
     
     
    +t = BoostBuild.Tester()
    +
    +t.write("jamfile.jam", """
    +my-test : test.cpp ;
     """)
     
    -t.write("test.cpp", """ 
    -int main()
    -{
    -    return 0;
    -}
    -
    +t.write("test.cpp", """
    +int main() {}
     """)
     
    -t.write("project-root.jam", """ using testing ;
    +t.write("jamroot.jam", """
    +using testing ;
     
     rule my-test ( name ? : sources + )
     {
    -    {
    -        name ?= test ;
    -        unit-test $(name) : $(sources) ; # /site-config//cppunit /util//testMain ;
    -    }   
    +    name ?= test ;
    +    unit-test $(name) : $(sources) ;  # /site-config//cppunit /util//testMain ;
     }
     
     IMPORT $(__name__) : my-test : : my-test ;
    -
    -
     """)
     
     t.run_build_system()
     t.expect_addition("bin/$toolset/debug/test.passed")
     
     t.cleanup()
    -
    diff --git a/v2/test/wrong_project.py b/v2/test/wrong_project.py
    index ef1ecc987..58d00d02e 100644
    --- a/v2/test/wrong_project.py
    +++ b/v2/test/wrong_project.py
    @@ -5,39 +5,28 @@
     # (See accompanying file LICENSE_1_0.txt
     # or copy at http://www.boost.org/LICENSE_1_0.txt)
     
    -# Regression test. When Jamfile contained "using whatever ; " and the
    -# 'whatever' module declared a project, then all targets in Jamfile were
    -# considered to be declared in the project associated with 'whatever',
    -# not with the Jamfile.
    +# Regression test. When Jamfile contained "using whatever ; " and the 'whatever'
    +# module declared a project, then all targets in Jamfile were considered to be
    +# declared in the project associated with 'whatever', not with the Jamfile.
     
    -from BoostBuild import Tester, List
    +import BoostBuild
     
    +t = BoostBuild.Tester()
     
    -t = Tester()
    -# Remove temporary directories
    +t.write("a.cpp", "int main() {}\n")
     
    -t.write("a.cpp", """ 
    -int main() { return 0; }
    -
    -""")
    -
    -t.write("Jamroot", """ 
    +t.write("jamroot.jam", """
     using some_tool ;
    -exe a : a.cpp ; 
    +exe a : a.cpp ;
     """)
     
    -t.write("some_tool.jam", """ 
    +t.write("some_tool.jam", """
     import project ;
     project.initialize $(__name__) ;
    -
    -rule init ( )
    -{
    -}
    -
    +rule init ( ) { }
     """)
     
     t.run_build_system()
     t.expect_addition("bin/$toolset/debug/a.exe")
     
     t.cleanup()
    -
    diff --git a/v2/tools/acc.jam b/v2/tools/acc.jam
    index 6a62859d9..e5a35b683 100644
    --- a/v2/tools/acc.jam
    +++ b/v2/tools/acc.jam
    @@ -19,15 +19,15 @@ toolset.inherit acc : unix ;
     generators.override builtin.lib-generator : acc.prebuilt ;
     generators.override acc.searched-lib-generator : searched-lib-generator ;
     
    -# Configures the acc toolset. 
    +# Configures the acc toolset.
     rule init ( version ? : user-provided-command * : options * )
     {
    -    local condition = [ common.check-init-parameters acc 
    +    local condition = [ common.check-init-parameters acc
             : version $(version) ] ;
    -    
    +
         local command = [ common.get-invocation-command acc : aCC
             : $(user-provided-command) ] ;
    -    
    +
         common.handle-options acc : $(condition) : $(command) : $(options) ;
     }
     
    @@ -81,6 +81,9 @@ flags acc FINDLIBS  ;
     flags acc CFLAGS multi : -mt   ;
     flags acc LINKFLAGS multi : -mt ;
     
    +flags acc.compile.c++ TEMPLATE_DEPTH  ;
    +
    +
     actions acc.link bind NEEDLIBS
     {
         $(CONFIG_COMMAND) -AA $(LINKFLAGS) -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) $(OPTIONS)
    @@ -93,13 +96,13 @@ actions acc.link.dll bind NEEDLIBS
     }
     
     actions acc.compile.c
    -{    
    -    $(CONFIG_COMMAND) -Ae -c -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" $(OPTIONS)
    +{
    +    cc -c -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" $(OPTIONS)
     }
     
     actions acc.compile.c++
     {
    -    $(CONFIG_COMMAND) -AA -c -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" $(OPTIONS)
    +    $(CONFIG_COMMAND) -AA -c -Wc,--pending_instantiations=$(TEMPLATE_DEPTH) -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" $(OPTIONS)
     }
     
     actions updated together piecemeal acc.archive
    diff --git a/v2/tools/boostbook-config.jam b/v2/tools/boostbook-config.jam
    index 9e8cf5c53..0b91705f4 100644
    --- a/v2/tools/boostbook-config.jam
    +++ b/v2/tools/boostbook-config.jam
    @@ -21,9 +21,11 @@ if [ os.name ] = NT
                 : "InstallRoot" ] ;
         }
         # Plausible locations.
    -    docbook_xsl-path ?= [ GLOB "$(boost-dir)\\share" "\\Boost\\share" : docbook-xsl* ] ;
    -    docbook_dtd-path ?= [ GLOB "$(boost-dir)\\share" "\\Boost\\share" : docbook-xml* ] ;
    -    boostbook-path ?= [ GLOB "$(boost-dir)\\share" "\\Boost\\share" : boostbook* ] ;
    +    local root = [ PWD ] ;
    +    while $(root) != $(root:D) { root = $(root:D) ; }
    +    docbook_xsl-path ?= [ GLOB "$(boost-dir)\\share" "$(root)Boost\\share" : docbook-xsl* ] ;
    +    docbook_dtd-path ?= [ GLOB "$(boost-dir)\\share" "$(root)Boost\\share" : docbook-xml* ] ;
    +    boostbook-path ?= [ GLOB "$(boost-dir)\\share" "$(root)Boost\\share" : boostbook* ] ;
         
         docbook_xsl-path = $(docbook_xsl-path[1]) ;
         docbook_dtd-path = $(docbook_dtd-path[1]) ;
    diff --git a/v2/tools/builtin.jam b/v2/tools/builtin.jam
    index 900c673dc..d3aeb17b8 100644
    --- a/v2/tools/builtin.jam
    +++ b/v2/tools/builtin.jam
    @@ -6,15 +6,14 @@
     # Distributed under the Boost Software License, Version 1.0.
     # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
     
    -#  Defines standard features and rules.
    +# Defines standard features and rules.
     
     import alias ;
     import "class" : new ;
    -import feature : feature compose ;
    -import toolset : flags ;
    -import errors : error ;
    -import generate ;
    +import errors ;
    +import feature ;
     import generators ;
    +import numbers ;
     import os ;
     import print ;
     import project ;
    @@ -23,10 +22,17 @@ import regex ;
     import scanner ;
     import stage ;
     import symlink ;
    +import toolset ;
     import type ;
    +import types/register ;
     import utility ;
     import virtual-target ;
    -import types/register ;
    +import message ;
    +
    +# FIXME: the following generate module import is not needed here but removing it
    +# too hastly will break using code (e.g. the main Boost library Jamroot file)
    +# that forgot to import the generate module before calling the generate rule.
    +import generate ;
     
     
     .os-names = amiga aix bsd cygwin darwin dos emx freebsd hpux iphone linux netbsd
    @@ -125,12 +131,12 @@ feature.feature location-prefix : : free ;
     #    unit-test a : a.cpp : b ;
     #    lib b : a.cpp b ;
     #
    -# Here, if  is not incidental, we'll decide we have two targets for a.obj
    -# with different properties, and will complain.
    +# Here, if  is not incidental, we would decide we have two targets for
    +# a.obj with different properties and complain about it.
     #
    -# Note that making feature incidental does not mean it's ignored. It may be
    -# ignored when creating the virtual target, but the rest of build process will
    -# use them.
    +# Note that making a feature incidental does not mean it is ignored. It may be
    +# ignored when creating a virtual target, but the rest of build process will use
    +# them.
     feature.feature use                 : : free dependency incidental ;
     feature.feature dependency          : : free dependency incidental ;
     feature.feature implicit-dependency : : free dependency incidental ;
    @@ -146,6 +152,29 @@ feature.feature warnings-as-errors :
         on         # Fail the compilation if there are warnings.
       : incidental propagated ;
     
    +# Feature that allows us to configure the maximal template instantiation depth
    +# level allowed by a C++ compiler. Applies only to C++ toolsets whose compilers
    +# actually support this configuration setting.
    +#
    +# Note that Boost Build currently does not allow defining features that take any
    +# positive integral value as a parameter, which is what we need here, so we just
    +# define some of the values here and leave it up to the user to extend this set
    +# as he needs using the feature.extend rule.
    +#
    +# TODO: This should be upgraded as soon as Boost Build adds support for custom
    +# validated feature values or at least features allowing any positive integral
    +# value. See related Boost Build related trac ticket #194.
    +#
    +feature.feature c++-template-depth
    +    :
    +        [ numbers.range 64 1024 : 64 ]
    +        [ numbers.range 20 1000 : 10 ]
    +        #   Maximum template instantiation depth guaranteed for ANSI/ISO C++
    +        # conforming programs.
    +        17
    +    :
    +        incidental optional propagated ;
    +
     feature.feature source              :            : free dependency incidental ;
     feature.feature library             :            : free dependency incidental ;
     feature.feature file                :            : free dependency incidental ;
    @@ -165,8 +194,8 @@ feature.feature hardcode-dll-paths  : true false : incidental ;
     
     
     # An internal feature that holds the paths of all dependency shared libraries.
    -# On Windows, it's needed so that we can add all those paths to PATH when
    -# running applications. On Linux, it's needed to add proper -rpath-link command
    +# On Windows, it is needed so that we can add all those paths to PATH when
    +# running applications. On Linux, it is needed to add proper -rpath-link command
     # line options.
     feature.feature xdll-path : : free path ;
     
    @@ -207,7 +236,7 @@ feature.feature architecture :
     
         # HP/PA-RISC
         parisc
    -    
    +
         # Advanced RISC Machines
         arm
     
    @@ -247,7 +276,7 @@ feature.feature instruction-set :
     
         # 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
     
    @@ -386,6 +415,7 @@ class c-scanner : scanner
         import path ;
         import regex ;
         import scanner ;
    +    import sequence ;
         import virtual-target ;
     
         rule __init__ ( includes * )
    @@ -394,7 +424,8 @@ class c-scanner : scanner
     
             for local i in $(includes)
             {
    -            self.includes += [ path.native $(i:G=) ] ;
    +            self.includes += [ sequence.transform path.native
    +                                : [ regex.split $(i:G=) "&&" ] ] ;
             }
         }
     
    @@ -415,9 +446,9 @@ class c-scanner : scanner
             # Attach binding of including file to included targets. When a target is
             # directly created from virtual target this extra information is
             # unnecessary. But in other cases, it allows us to distinguish between
    -        # two headers of the same name included from different places. We don't
    +        # two headers of the same name included from different places. We do not
             # need this extra information for angle includes, since they should not
    -        # depend on including file (we can't get literal "." in include path).
    +        # depend on including file (we can not get literal "." in include path).
             local g2 = $(g)"#"$(b) ;
     
             angle = $(angle:G=$(g)) ;
    @@ -480,7 +511,7 @@ class lib-generator : generator
                 # Determine the needed target type.
                 local actual-type ;
                     # files can be generated by @rule feature
    -                # in which case we don't consider it a SEARCHED_LIB type.
    +                # in which case we do not consider it a SEARCHED_LIB type.
                 if !  in $(properties:G) &&
                    (  in $(properties:G) ||  in $(properties:G) )
                 {
    @@ -518,20 +549,20 @@ generators.register [ new lib-generator builtin.lib-generator :  : LIB ] ;
     # 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 * )
    +rule lib ( names + : sources * : requirements * : default-build * :
    +    usage-requirements * )
     {
         if $(names[2])
         {
             if  in $(requirements:G)
             {
                 errors.user-error "When several names are given to the 'lib' rule" :
    -                "it's not allowed to specify the  feature." ;
    +                "it is not allowed to specify the  feature." ;
             }
             if $(sources)
             {
                 errors.user-error "When several names are given to the 'lib' rule" :
    -                "it's not allowed to specify sources." ;
    +                "it is not allowed to specify sources." ;
             }
         }
     
    @@ -599,7 +630,7 @@ class searched-lib-generator : generator
                 lib-name ?= $(name) ;
                 local t = [ new searched-lib-target $(lib-name) : $(project)
                     : $(shared) : $(search) : $(a) ] ;
    -            # We return sources for a simple reason. If there's
    +            # We return sources for a simple reason. If there is
                 #    lib png : z : png ;
                 # the 'z' target should be returned, so that apps linking to 'png'
                 # will link to 'z', too.
    @@ -677,11 +708,11 @@ class C-compiling-generator : generator
     rule register-c-compiler ( id : source-types + : target-types + : requirements *
         : optional-properties * )
     {
    -    generators.register [ new C-compiling-generator $(id) : $(source-types)
    -        : $(target-types) : $(requirements) : $(optional-properties) ] ;
    +    generators.register [ new C-compiling-generator $(id) : $(source-types) :
    +        $(target-types) : $(requirements) : $(optional-properties) ] ;
     }
     
    -# FIXME: this is ugly, should find a better way (we'd like client code to
    +# FIXME: this is ugly, should find a better way (we would like client code to
     # register all generators as "generators.some-rule" instead of
     # "some-module.some-rule".)
     #
    @@ -726,18 +757,22 @@ class linking-generator : generator
                 }
             }
     
    -        # It's possible that sources include shared libraries that did not came
    +        # It is possible that sources include shared libraries that did not came
             # from 'lib' targets, e.g. .so files specified as sources. In this case
             # we have to add extra dll-path properties and propagate extra xdll-path
    -        # properties so that application linking to use will get xdll-path to
    +        # properties so that application linking to us will get xdll-path to
             # those libraries.
             local extra-xdll-paths ;
             for local s in $(sources)
             {
                 if [ type.is-derived [ $(s).type ] SHARED_LIB ] && ! [ $(s).action ]
                 {
    -                # Unfortunately, we don't have a good way to find the path to a
    +                # Unfortunately, we do not have a good way to find the path to a
                     # file, so use this nasty approach.
    +                #
    +                # TODO: This needs to be done better. One thing that is really
    +                # broken with this is that it does not work correctly with
    +                # projects having multiple source locations.
                     local p = [ $(s).project ] ;
                     local location = [ path.root [ $(s).name ]
                         [ $(p).get source-location ] ] ;
    @@ -746,8 +781,8 @@ class linking-generator : generator
             }
     
             # Hardcode DLL paths only when linking executables.
    -        # Pros: don't need to relink libraries when installing.
    -        # Cons: "standalone" libraries (plugins, python extensions) can't
    +        # Pros: do not need to relink libraries when installing.
    +        # Cons: "standalone" libraries (plugins, python extensions) can not
             # hardcode paths to dependent libraries.
             if [ $(property-set).get  ] = true
                 && [ type.is-derived $(self.target-types[1]) EXE ]
    @@ -800,9 +835,9 @@ class linking-generator : generator
             # to other shared libraries this one depends on in order to be able to
             # find them all at runtime.
     
    -        # Just pass all features in property-set, it's theorically possible that
    -        # we'll propagate  features explicitly specified by the user,
    -        # but then the user's to blaim for using an internal feature.
    +        # Just pass all features in property-set, it is theorically possible
    +        # that we will propagate  features explicitly specified by
    +        # the user, but then the user is to blaim for using an internal feature.
             local values = [ $(property-set).get  ] ;
             extra += $(values:G=) ;
     
    @@ -881,7 +916,7 @@ class archive-generator : generator
             local result = [ generator.run $(project) $(name) : $(property-set)
                 : $(sources) ] ;
     
    -        # For static linking, if we get a library in source, we can't directly
    +        # For static linking, if we get a library in source, we can not directly
             # link to it so we need to cause our dependencies to link to that
             # library. There are two approaches:
             # - adding the library to the list of returned targets.
    @@ -892,11 +927,11 @@ class archive-generator : generator
             #     lib a2 : a2.cpp a1 : static ;
             #     install dist : a2 ;
             #
    -        # here we'll try to install 'a1', even though it's not necessary in the
    -        # general case. With the second approach, even indirect dependants will
    -        # link to the library, but it should not cause any harm. So, return all
    -        # LIB sources together with created targets, so that dependants link to
    -        # them.
    +        # here we will try to install 'a1', even though it is not necessary in
    +        # the general case. With the second approach, even indirect dependants
    +        # will link to the library, but it should not cause any harm. So, return
    +        # all LIB sources together with created targets, so that dependants link
    +        # to them.
             local usage-requirements ;
             if [ $(property-set).get  ] = static
             {
    diff --git a/v2/tools/cast.jam b/v2/tools/cast.jam
    index 407980686..6c84922f1 100644
    --- a/v2/tools/cast.jam
    +++ b/v2/tools/cast.jam
    @@ -3,24 +3,25 @@
     # accompanying file LICENSE_1_0.txt or copy at
     # http://www.boost.org/LICENSE_1_0.txt)
     
    -# Defines main target 'cast', used to change type for target. For example,
    -# in Qt library one wants two kinds of CPP files -- those that just compiled
    -# and those that are passed via the MOC tool.
    +# Defines main target 'cast', used to change type for target. For example, in Qt
    +# library one wants two kinds of CPP files -- those that just compiled and those
    +# that are passed via the MOC tool.
     #
     # This is done with:
     #
     #    exe main : main.cpp [ cast _ moccable-cpp : widget.cpp ] ;
     #
    -# Boost.Build will assing target type CPP to both main.cpp and widget.cpp.
    -# Then, the cast rule will change target type of widget.cpp to
    -# MOCCABLE-CPP, and Qt support will run MOC tool as part of build process.
    +# Boost.Build will assing target type CPP to both main.cpp and widget.cpp. Then,
    +# the cast rule will change target type of widget.cpp to MOCCABLE-CPP, and Qt
    +# support will run the MOC tool as part of the build process.
     #
     # At the moment, the 'cast' rule only works for non-derived (source) targets.
     #
    -# Another solution would be to add separate main target 'moc-them' that
    -# will moc all the passed sources, not matter what's the type, but I prefer
    -# cast, as defining new target type + generator for that type is somewhat
    -# simpler then defining main target rule.
    +# TODO: The following comment is unclear or incorrect. Clean it up.
    +# > Another solution would be to add a separate main target 'moc-them' that
    +# > would moc all the passed sources, no matter what their type is, but I prefer
    +# > cast, as defining a new target type + generator for that type is somewhat
    +# > simpler than defining a main target rule.
     
     import "class" : new ;
     import errors ;
    @@ -34,11 +35,11 @@ class cast-target-class : typed-target
     {
         import type ;
     
    -    rule __init__ ( name : project : type : sources * : requirements *
    -        : default-build * : usage-requirements * )
    +    rule __init__ ( name : project : type : sources * : requirements * :
    +        default-build * : usage-requirements * )
         {
    -        typed-target.__init__ $(name) : $(project) : $(type) : $(sources)
    -            : $(requirements) : $(default-build) : $(usage-requirements) ;
    +        typed-target.__init__ $(name) : $(project) : $(type) : $(sources) :
    +            $(requirements) : $(default-build) : $(usage-requirements) ;
         }
     
         rule construct ( name : source-targets * : property-set )
    @@ -48,14 +49,14 @@ class cast-target-class : typed-target
             {
                 if ! [ class.is-a $(s) : file-target ]
                 {
    -                ECHO "error: source to the 'cast' rule is not a file!" ;
    -                EXIT ;
    +                import errors ;
    +                errors.user-error Source to the 'cast' rule is not a file! ;
                 }
                 if [ $(s).action ]
                 {
    -                ECHO "error: only non-derived target are allowed for 'cast'." ;
    -                ECHO "error: when building " [ full-name ] ;
    -                EXIT ;
    +                import errors ;
    +                errors.user-error Only non-derived target are allowed for
    +                    'cast'. : when building [ full-name ] ;
                 }
                 local r = [ $(s).clone-with-different-type $(self.type) ] ;
                 result += [ virtual-target.register $(r) ] ;
    @@ -65,27 +66,26 @@ class cast-target-class : typed-target
     }
     
     
    -rule cast ( name type : sources * : requirements * : default-build *
    -    : usage-requirements * )
    +rule cast ( name type : sources * : requirements * : default-build * :
    +    usage-requirements * )
     {
         local project = [ project.current ] ;
     
         local real-type = [ type.type-from-rule-name $(type) ] ;
         if ! $(real-type)
         {
    -        errors.user-error "No type corresponds to main target rule name '$(type)'"
    -            : "Hint: try lowercase name" ;
    +        errors.user-error No type corresponds to the main target rule name
    +            '$(type)' : "Hint: try a lowercase name" ;
         }
     
    -    # This is a circular module dependency so it must be imported here.
    -    import targets ;
    -    targets.main-target-alternative
    -        [ new cast-target-class $(name) : $(project) : $(real-type)
    -            : [ targets.main-target-sources $(sources) : $(name) ]
    -            : [ targets.main-target-requirements $(requirements) : $(project) ]
    -            : [ targets.main-target-default-build $(default-build) : $(project) ]
    -            : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
    -        ] ;
    +    targets.main-target-alternative [ new cast-target-class $(name) : $(project)
    +        : $(real-type)
    +        : [ targets.main-target-sources $(sources) : $(name) ]
    +        : [ targets.main-target-requirements $(requirements) : $(project) ]
    +        : [ targets.main-target-default-build $(default-build) : $(project) ]
    +        : [ targets.main-target-usage-requirements $(usage-requirements) :
    +            $(project) ] ] ;
     }
     
    +
     IMPORT $(__name__) : cast : : cast ;
    diff --git a/v2/tools/common.jam b/v2/tools/common.jam
    index 87424bfc3..73cc56fa3 100644
    --- a/v2/tools/common.jam
    +++ b/v2/tools/common.jam
    @@ -40,9 +40,9 @@ if [ MATCH (--show-configuration) : [ modules.peek : ARGV ] ]
     # A toolset configuration may be in one of the following states:
     #
     #   - registered
    -#       Configuration has been registered (e.g. by autodetection code) but has
    -#       not yet been marked as used, i.e. 'toolset.using' rule has not yet been
    -#       called for it.
    +#       Configuration has been registered (e.g. explicitly or by auto-detection
    +#       code) but has not yet been marked as used, i.e. 'toolset.using' rule has
    +#       not yet been called for it.
     #   - used
     #       Once called 'toolset.using' rule marks the configuration as 'used'.
     #
    @@ -87,8 +87,8 @@ class configurations
         # Mark a configuration as 'used'.
         #
         # 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.
    +    # 'used' and an empty value if it the state has not been changed. Reports an
    +    # error if the configuration is not known.
         #
         rule use ( id )
         {
    @@ -103,7 +103,7 @@ class configurations
             {
                 self.used += $(id) ;
     
    -            # indicate that the configuration has been marked as 'used'
    +            # Indicate that the configuration has been marked as 'used'.
                 retval = true ;
             }
     
    @@ -168,13 +168,13 @@ rule check-init-parameters ( toolset requirement * : * )
                 if $(.had-unspecified-value.$(toolset).$(name))
                 {
                     errors.user-error
    -                "$(toolset) initialization: parameter '$(name)' inconsistent" :
    -                "no value was specified in earlier initialization" :
    -                "an explicit value is specified now" ;
    +                    "$(toolset) initialization: parameter '$(name)'"
    +                    "inconsistent" : "no value was specified in earlier"
    +                    "initialization" : "an explicit value is specified now" ;
                 }
                 # The below logic is for intel compiler. It calls this rule with
                 # 'intel-linux' and 'intel-win' as toolset, so we need to get the
    -            # base part of toolset name. We can't pass 'intel' as toolset
    +            # base part of toolset name. We can not pass 'intel' as toolset
                 # because in that case it will be impossible to register versionless
                 # intel-linux and intel-win toolsets of a specific version.
                 local t = $(toolset) ;
    @@ -200,9 +200,9 @@ rule check-init-parameters ( toolset requirement * : * )
                 if $(.had-value.$(toolset).$(name))
                 {
                     errors.user-error
    -                "$(toolset) initialization: parameter '$(name)' inconsistent" :
    -                "an explicit value was specified in an earlier initialization" :
    -                "no value is specified now" ;
    +                    "$(toolset) initialization: parameter '$(name)'"
    +                    "inconsistent" : "an explicit value was specified in an"
    +                    "earlier initialization" : "no value is specified now" ;
                 }
                 .had-unspecified-value.$(toolset).$(name) = true ;
             }
    @@ -255,30 +255,30 @@ rule check-init-parameters ( toolset requirement * : * )
     # PATH and in the passed 'additional-path'. Otherwise, verifies that the first
     # element of 'user-provided-command' is an existing program.
     #
    -# This rule returns the command to be used when invoking the tool. If we can't
    +# This rule returns the command to be used when invoking the tool. If we can not
     # 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 ? )
    +rule get-invocation-command-nodefault ( toolset : tool :
    +    user-provided-command * : additional-paths * : path-last ? )
     {
         local command ;
         if ! $(user-provided-command)
         {
    -        command = [ common.find-tool $(tool) : $(additional-paths) : $(path-last) ] ;
    +        command = [ find-tool $(tool) : $(additional-paths) : $(path-last) ] ;
             if ! $(command) && $(.debug-configuration)
             {
    -            ECHO "warning: toolset $(toolset) initialization: can't find tool $(tool)" ;
    +            ECHO "warning: toolset $(toolset) initialization: can not find tool $(tool)" ;
                 ECHO "warning: initialized from" [ errors.nearest-user-location ] ;
             }
         }
         else
         {
    -        command = [ common.check-tool $(user-provided-command) ] ;
    +        command = [ check-tool $(user-provided-command) ] ;
             if ! $(command) && $(.debug-configuration)
             {
                 ECHO "warning: toolset $(toolset) initialization: " ;
    -            ECHO "warning: can't find user-provided command " '$(user-provided-command)' ;
    +            ECHO "warning: can not find user-provided command " '$(user-provided-command)' ;
                 ECHO "warning: initialized from" [ errors.nearest-user-location ] ;
             }
         }
    @@ -290,11 +290,11 @@ rule get-invocation-command-nodefault (
     # 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 ? )
    +rule get-invocation-command ( toolset : tool : user-provided-command * :
    +    additional-paths * : path-last ? )
     {
    -    local result = [ get-invocation-command-nodefault $(toolset) : $(tool)
    -        : $(user-provided-command) : $(additional-paths) : $(path-last) ] ;
    +    local result = [ get-invocation-command-nodefault $(toolset) : $(tool) :
    +        $(user-provided-command) : $(additional-paths) : $(path-last) ] ;
     
         if ! $(result)
         {
    @@ -334,7 +334,7 @@ rule get-absolute-tool-path ( command )
     # 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 rule find-tool ( name : additional-paths * : path-last ? )
     {
         local path = [ path.programs-path ] ;
         local match = [ path.glob $(path) : $(name) $(name).exe ] ;
    @@ -370,15 +370,16 @@ rule find-tool ( name : additional-paths * : path-last ? )
     # Checks if 'command' can be found either in path or is a full name to an
     # existing file.
     #
    -rule check-tool-aux ( command )
    +local 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 ] )
    -            # Only NT will run .bat files by their unqualified names.
    -            || ( ( [ os.name ] = NT ) && [ path.exists $(command).bat ] )
    +            # Only NT will run .bat & .cmd files by their unqualified names.
    +            || ( ( [ os.name ] = NT ) && ( [ path.exists $(command).bat ] ||
    +                [ path.exists $(command).cmd ] ) )
             {
                 return $(command) ;
             }
    @@ -397,7 +398,7 @@ rule check-tool-aux ( command )
     # 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 + )
    +local rule check-tool ( xcommand + )
     {
         if [ check-tool-aux $(xcommand[1]) ] ||
            [ check-tool-aux $(xcommand[-1]) ]
    @@ -721,13 +722,13 @@ actions hard-link
     #   [joiner]
     #       ::  Collective tag of the build runtime.
     #   [joiner]
    -#       ::  Short version tag taken from the given "version-feature"
    -#           in the build properties. Or if not present, the literal
    -#           value as the version number.
    +#       ::  Short version tag taken from the given "version-feature" in the
    +#           build properties. Or if not present, the literal value as the
    +#           version number.
     #   [joiner]
    -#       ::  Direct lookup of the given property-name value in the
    -#           build properties. /property-name/ is a regular expression.
    -#           e.g.  will match every toolset.
    +#       ::  Direct lookup of the given property-name value in the build
    +#           properties. /property-name/ is a regular expression. E.g.
    +#            will match every toolset.
     #   /otherwise/
     #       ::  The literal value of the format argument.
     #
    @@ -756,29 +757,30 @@ rule format-name ( format * : name : type ? : property-set )
                     result += $(name:B) ;
     
                     case  :
    -                result += [ join-tag $(f:G=) :
    -                    [ toolset-tag $(name) : $(type) : $(property-set) ] ] ;
    +                result += [ join-tag $(f:G=) : [ toolset-tag $(name) : $(type) :
    +                    $(property-set) ] ] ;
     
                     case  :
    -                result += [ join-tag $(f:G=) :
    -                    [ threading-tag $(name) : $(type) : $(property-set) ] ] ;
    +                result += [ join-tag $(f:G=) : [ threading-tag $(name) : $(type)
    +                    : $(property-set) ] ] ;
     
                     case  :
    -                result += [ join-tag $(f:G=) :
    -                    [ runtime-tag $(name) : $(type) : $(property-set) ] ] ;
    +                result += [ join-tag $(f:G=) : [ runtime-tag $(name) : $(type) :
    +                    $(property-set) ] ] ;
     
                     case  :
                     local key = [ MATCH  : $(f:G) ] ;
                     local version = [ $(property-set).get <$(key)> ] ;
                     version ?= $(key) ;
    -                version = [ MATCH "^([^.]+)[.]([^.]+)[.]?([^.]*)"
    -                    : $(version) ] ;
    +                version = [ MATCH "^([^.]+)[.]([^.]+)[.]?([^.]*)" : $(version) ]
    +                    ;
                     result += [ join-tag $(f:G=) : $(version[1])_$(version[2]) ] ;
     
                     case  :
                     local key = [ MATCH  : $(f:G) ] ;
                     local p0 = [ MATCH <($(key))> : [ $(property-set).raw ] ] ;
    -                if $(p0) {
    +                if $(p0)
    +                {
                         local p = [ $(property-set).get <$(p0)> ] ;
                         if $(p)
                         {
    @@ -790,8 +792,8 @@ rule format-name ( format * : name : type ? : property-set )
                     result += $(f:G=) ;
                 }
             }
    -        result = [ virtual-target.add-prefix-and-suffix
    -            $(result:J=) : $(type) : $(property-set) ] ;
    +        result = [ virtual-target.add-prefix-and-suffix $(result:J=) : $(type) :
    +            $(property-set) ] ;
             return $(result) ;
         }
     }
    @@ -895,14 +897,14 @@ local rule runtime-tag ( name : type ? : property-set )
         local properties = [ $(property-set).raw ] ;
         if static in $(properties) { tag += s ; }
     
    -    # This is an ugly thing. In V1, there's a code to automatically detect which
    +    # This is an ugly thing. In V1, there is code to automatically detect which
         # properties affect a target. So, if  does not affect gcc
    -    # toolset, the tag rules won't even see . Similar
    +    # toolset, the tag rules will not even see . Similar
         # functionality in V2 is not implemented yet, so we just check for toolsets
    -    # which are known to care about runtime debug.
    -    if msvc in $(properties)
    -      || stlport in $(properties)
    -      || win in $(properties)
    +    # known to care about runtime debugging.
    +    if ( msvc in $(properties) ) ||
    +        ( stlport in $(properties) ) ||
    +        ( win in $(properties) )
         {
             if on in $(properties) { tag += g ; }
         }
    diff --git a/v2/tools/cw.jam b/v2/tools/cw.jam
    index 07eec5a52..ddcbfeb2b 100644
    --- a/v2/tools/cw.jam
    +++ b/v2/tools/cw.jam
    @@ -43,7 +43,7 @@ rule init ( version ? : command * : options * )
             version $(version) ] ;
     
         command = [ common.get-invocation-command cw : mwcc.exe : $(command) :
    -      [ default-paths $(version) ] ] ;
    +        [ default-paths $(version) ] ] ;
         
         common.handle-options cw : $(condition) : $(command) : $(options) ;
     
    @@ -103,7 +103,8 @@ rule init ( version ? : command * : options * )
         }    
     }
     
    -rule default-paths ( version ? ) # FIXME
    +
    +local rule default-paths ( version ? )  # FIXME
     {
        local possible-paths ;
        local ProgramFiles = [ common.get-program-files-dir ] ;
    diff --git a/v2/tools/darwin.jam b/v2/tools/darwin.jam
    index f5e272ed6..c6ccd31a2 100644
    --- a/v2/tools/darwin.jam
    +++ b/v2/tools/darwin.jam
    @@ -350,10 +350,14 @@ rule link
         prepare-framework-path $(<) ;
     }
     
    +# Note that using strip without any options was reported to result in broken
    +# binaries, at least on OS X 10.5.5, see:
    +#    http://svn.boost.org/trac/boost/ticket/2347
    +# So we pass -S -x.
     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)"$(<)"
    +    $(NEED_STRIP)"$(.STRIP)" $(NEED_STRIP)-S $(NEED_STRIP)-x $(NEED_STRIP)"$(<)"
     }
     
     rule link.dll
    diff --git a/v2/tools/gcc.jam b/v2/tools/gcc.jam
    index 47a19a0c5..3e5dca805 100644
    --- a/v2/tools/gcc.jam
    +++ b/v2/tools/gcc.jam
    @@ -10,19 +10,22 @@
     #    (See accompanying file LICENSE_1_0.txt or copy at
     #          http://www.boost.org/LICENSE_1_0.txt)
     
    -import toolset : flags ;
    -import property ;
    -import generators ;
    -import os ;
    -import type ;
    -import feature ;
     import "class" : new ;
    -import set ;
     import common ;
     import errors ;
    -import property-set ;
    +import feature ;
    +import generators ;
    +import os ;
     import pch ;
    +import property ;
    +import property-set ;
    +import toolset ;
    +import type ;
    +import rc ;
     import regex ;
    +import set ;
    +import unix ;
    +
     
     if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
     {
    @@ -32,7 +35,6 @@ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
     
     feature.extend toolset : gcc ;
     
    -import unix ;
     toolset.inherit-generators gcc : unix : unix.link unix.link.dll ;
     toolset.inherit-flags gcc : unix ;
     toolset.inherit-rules gcc : unix ;
    @@ -57,29 +59,31 @@ generators.override gcc.searched-lib-generator : searched-lib-generator ;
     #     xxx.dll      DLL
     #     libxxx.dll.a import library
     #
    -# Note: user can always override by using the @rule
    -#       This settings have been choosen, so that mingw
    -#       is in line with msvc naming conventions. For
    -#       cygwin the cygwin naming convention has been choosen.
    +# Implementation notes:
    +#   * User can always override this by using the @rule.
    +#   * These settings have been chosen so that mingw is in line with msvc naming
    +#     conventions.
    +#   * For cygwin the cygwin naming convention has been chosen.
     
    -# Make the "o" suffix used for gcc toolset on all
    -# platforms
    +# Make gcc toolset object files use the "o" suffix on all platforms.
     type.set-generated-target-suffix OBJ : gcc : o ;
    -type.set-generated-target-suffix STATIC_LIB : gcc cygwin : a ;
    +type.set-generated-target-suffix OBJ : gcc windows : o ;
    +type.set-generated-target-suffix OBJ : gcc cygwin : o ;
     
    +type.set-generated-target-suffix STATIC_LIB : gcc cygwin : a ;
     type.set-generated-target-suffix IMPORT_LIB : gcc cygwin : dll.a ;
     type.set-generated-target-prefix IMPORT_LIB : gcc cygwin : lib ;
     
    -import rc ;
     
     # Initializes the gcc toolset for the given version. If necessary, command may
     # be used to specify where the compiler is located. The parameter 'options' is a
     # space-delimited list of options, each one specified as
     # option-value. Valid option names are: cxxflags, linkflags and
    -# linker-type. Accepted linker-type values are gnu, darwin, osf, hpux or sun
    -# and the default value will be selected based on the current OS.
    +# linker-type. Accepted linker-type values are aix, darwin, gnu, hpux, osf or
    +# sun and the default value will be selected based on the current OS.
     # Example:
     #   using gcc : 3.4 : : foo bar sun ;
    +#
     rule init ( version ? : command * : options * )
     {
         # Information about the gcc command...
    @@ -167,7 +171,7 @@ rule init ( version ? : command * : options * )
             {
                 ECHO notice: using gcc libraries :: $(condition) :: $(lib_path) ;
             }
    -        flags gcc.link RUN_PATH $(condition) : $(lib_path) ;
    +        toolset.flags gcc.link RUN_PATH $(condition) : $(lib_path) ;
         }
     
         # If it's not a system gcc install we should adjust the various programs as
    @@ -178,7 +182,7 @@ rule init ( version ? : command * : options * )
         local archiver =
             [ common.get-invocation-command gcc
                 : ar : [ feature.get-values  : $(options) ] : $(bin) : search-path ] ;
    -    flags gcc.archive .AR $(condition) : $(archiver[1]) ;
    +    toolset.flags gcc.archive .AR $(condition) : $(archiver[1]) ;
         if $(.debug-configuration)
         {
             ECHO notice: using gcc archiver :: $(condition) :: $(archiver[1]) ;
    @@ -284,79 +288,101 @@ generators.register [ new gcc-pch-generator gcc.compile.c++.pch : H : CPP_PCH :
     generators.override gcc.compile.c.pch   : pch.default-c-pch-generator   ;
     generators.override gcc.compile.c++.pch : pch.default-cpp-pch-generator ;
     
    -flags gcc.compile PCH_FILE on :  ;
    +toolset.flags gcc.compile PCH_FILE on :  ;
     
    -# Declare flags and action for compilation
    -flags gcc.compile OPTIONS off   : -O0 ;
    -flags gcc.compile OPTIONS speed : -O3 ;
    -flags gcc.compile OPTIONS space : -Os ;
    +# Declare flags and action for compilation.
    +toolset.flags gcc.compile OPTIONS off   : -O0 ;
    +toolset.flags gcc.compile OPTIONS speed : -O3 ;
    +toolset.flags gcc.compile OPTIONS space : -Os ;
     
    -flags gcc.compile OPTIONS off  : -fno-inline ;
    -flags gcc.compile OPTIONS on   : -Wno-inline ;
    -flags gcc.compile OPTIONS full : -finline-functions -Wno-inline ;
    +toolset.flags gcc.compile OPTIONS off  : -fno-inline ;
    +toolset.flags gcc.compile OPTIONS on   : -Wno-inline ;
    +toolset.flags gcc.compile OPTIONS full : -finline-functions -Wno-inline ;
     
    -flags gcc.compile OPTIONS off : -w ;
    -flags gcc.compile OPTIONS on  : -Wall ;
    -flags gcc.compile OPTIONS all : -Wall -pedantic ;
    -flags gcc.compile OPTIONS on : -Werror ;
    +toolset.flags gcc.compile OPTIONS off : -w ;
    +toolset.flags gcc.compile OPTIONS on  : -Wall ;
    +toolset.flags gcc.compile OPTIONS all : -Wall -pedantic ;
    +toolset.flags gcc.compile OPTIONS on : -Werror ;
     
    -flags gcc.compile OPTIONS on : -g ;
    -flags gcc.compile OPTIONS on : -pg ;
    -flags gcc.compile OPTIONS off : -fno-rtti ;
    +toolset.flags gcc.compile OPTIONS on : -g ;
    +toolset.flags gcc.compile OPTIONS on : -pg ;
    +toolset.flags gcc.compile OPTIONS off : -fno-rtti ;
     
    -# On cygwin and mingw, gcc generates position independent code by default, and
    -# warns if -fPIC is specified. This might not be the right way of checking if
    -# we're using cygwin. For example, it's possible to run cygwin gcc from NT
    -# shell, or using crosscompiling. But we'll solve that problem when it's time.
    -# In that case we'll just add another parameter to 'init' and move this login
    -# inside 'init'.
    -if [ os.name ] != CYGWIN && [ os.name ] != NT
    +rule setup-fpic ( targets * : sources * : properties * )
     {
    -    # This logic will add -fPIC for all compilations:
    -    #
    -    # lib a : a.cpp b ;
    -    # obj b : b.cpp ;
    -    # exe c : c.cpp a d ;
    -    # obj d : d.cpp ;
    -    #
    -    # This all is fine, except that 'd' will be compiled with -fPIC even though
    -    # it's not needed, as 'd' is used only in exe. However, it's hard to detect
    -    # where a target is going to be used. Alternative, we can set -fPIC only
    -    # when main target type is LIB but than 'b' will be compiled without -fPIC.
    -    # In x86-64 that will lead to link errors. So, compile everything with
    -    # -fPIC.
    -    #
    -    # Yet another alternative would be to create propagated 
    -    # feature, and set it when building shared libraries, but that's hard to
    -    # implement and will increase target path length even more.
    -    flags gcc.compile OPTIONS shared : -fPIC ;
    +    local link = [ feature.get-values link : $(properties) ] ;
    +    if $(link) = shared
    +    {        
    +        local target = [ feature.get-values target-os : $(properties) ] ;
    +        
    +        # This logic will add -fPIC for all compilations:
    +        #
    +        # lib a : a.cpp b ;
    +        # obj b : b.cpp ;
    +        # exe c : c.cpp a d ;
    +        # obj d : d.cpp ;
    +        #
    +        # This all is fine, except that 'd' will be compiled with -fPIC even though
    +        # it is not needed, as 'd' is used only in exe. However, it is hard to
    +        # detect where a target is going to be used. Alternatively, we can set -fPIC
    +        # only when main target type is LIB but than 'b' would be compiled without
    +        # -fPIC which would lead to link errors on x86-64. So, compile everything
    +        # with -fPIC.
    +        #
    +        # Yet another alternative would be to create a propagated 
    +        # feature and set it when building shared libraries, but that would be hard
    +        # to implement and would increase the target path length even more.
    +        
    +        # On Windows, fPIC is default, specifying -fPIC explicitly leads to
    +        # a warning.
    +        if $(target) != cygwin && $(target) != windows
    +        {
    +            OPTIONS on $(targets) += -fPIC ;
    +        }        
    +    }
     }
    +
    +# FIXME: this should not use os.name.
     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
    +    # OSF does have an option called -soname but it does not seem to work as
         # expected, therefore it has been disabled.
         HAVE_SONAME   = "" ;
         SONAME_OPTION = -h ;
     }
     
     
    -flags gcc.compile USER_OPTIONS  ;
    -flags gcc.compile.c++ USER_OPTIONS  ;
    -flags gcc.compile DEFINES  ;
    -flags gcc.compile INCLUDES  ;
    +toolset.flags gcc.compile USER_OPTIONS  ;
    +toolset.flags gcc.compile.c++ USER_OPTIONS  ;
    +toolset.flags gcc.compile DEFINES  ;
    +toolset.flags gcc.compile INCLUDES  ;
    +toolset.flags gcc.compile.c++ TEMPLATE_DEPTH  ;
    +
    +rule compile.c++.pch ( targets * : sources * : properties * )
    +{
    +    setup-fpic $(targets) : $(sources) : $(properties) ;
    +}
     
     actions compile.c++.pch
     {
         "$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
     }
     
    +rule compile.c.pch ( targets * : sources * : properties * )
    +{
    +    setup-fpic $(targets) : $(sources) : $(properties) ;
    +}
    +
     actions compile.c.pch
     {
         "$(CONFIG_COMMAND)" -x c-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
     }
     
    -rule compile.c++
    +rule compile.c++ ( targets * : sources * : properties * )
     {
    +    setup-threading $(targets) : $(sources) : $(properties) ;
    +    setup-fpic $(targets) : $(sources) : $(properties) ;
    +    
         # Some extensions are compiled as C++ by default. For others, we need to
         # pass -x c++. We could always pass -x c++ but distcc does not work with it.
         if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C
    @@ -364,10 +390,28 @@ rule compile.c++
             LANG on $(<) = "-x c++" ;
         }
         DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ;
    +    
    +    # Here we want to raise the template-depth parameter value to something
    +    # higher than the default value of 17. Note that we could do this using the
    +    # feature.set-default rule but we do not want to set the default value for
    +    # all toolsets as well.
    +    #
    +    # TODO: This 'modified default' has been inherited from some 'older Boost
    +    # Build implementation' and has most likely been added to make some Boost
    +    # library parts compile correctly. We should see what exactly prompted this
    +    # and whether we can get around the problem more locally.
    +    local template-depth = [ on $(<) return $(TEMPLATE_DEPTH) ] ;
    +    if ! $(template-depth)
    +    {
    +        TEMPLATE_DEPTH on $(<) = 128 ;
    +    }
     }
     
    -rule compile.c
    +rule compile.c ( targets * : sources * : properties * )
     {
    +    setup-threading $(targets) : $(sources) : $(properties) ;
    +    setup-fpic $(targets) : $(sources) : $(properties) ;
    +    
         # If we use the name g++ then default file suffix -> language mapping does
         # not work. So have to pass -x option. Maybe, we can work around this by
         # allowing the user to specify both C and C++ compiler names.
    @@ -380,7 +424,7 @@ rule compile.c
     
     actions compile.c++ bind PCH_FILE
     {
    -    "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-128 $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<:W)" "$(>:W)"
    +    "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<:W)" "$(>:W)"
     }
     
     actions compile.c bind PCH_FILE
    @@ -487,13 +531,13 @@ else
     
     # Declare flags for linking.
     # First, the common flags.
    -flags gcc.link OPTIONS on : -g ;
    -flags gcc.link OPTIONS on : -pg ;
    -flags gcc.link USER_OPTIONS  ;
    -flags gcc.link LINKPATH  ;
    -flags gcc.link FINDLIBS-ST  ;
    -flags gcc.link FINDLIBS-SA  ;
    -flags gcc.link LIBRARIES  ;
    +toolset.flags gcc.link OPTIONS on : -g ;
    +toolset.flags gcc.link OPTIONS on : -pg ;
    +toolset.flags gcc.link USER_OPTIONS  ;
    +toolset.flags gcc.link LINKPATH  ;
    +toolset.flags gcc.link FINDLIBS-ST  ;
    +toolset.flags gcc.link FINDLIBS-SA  ;
    +toolset.flags gcc.link LIBRARIES  ;
     
     # For static we made sure there are no dynamic libraries in the
     # link. On HP-UX not all system libraries exist as archived libraries (for
    @@ -501,26 +545,64 @@ flags gcc.link LIBRARIES  ;
     # cannot be specified.
     if [ os.name ] != HPUX
     {
    -    flags gcc.link OPTIONS static : -static ;
    +    toolset.flags gcc.link OPTIONS static : -static ;
     }
     
     # Now, the vendor specific flags.
    -# The parameter linker can be either gnu, darwin, osf, hpux or sun.
    +# The parameter linker can be either aix, darwin, gnu, hpux, osf or sun.
     rule init-link-flags ( toolset linker condition )
     {
         switch $(linker)
         {
    +    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 the AIX linker see:
    +        # http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf
    +        #
    +
    +        toolset.flags $(toolset).link OPTIONS : -Wl,-brtl -Wl,-bnoipath
    +            : unchecked ;
    +        }
    +
    +    case darwin :
    +        {
    +        # On Darwin, the -s option to ld does not work unless we pass -static,
    +        # and passing -static unconditionally is a bad idea. So, don't pass -s.
    +        # at all, darwin.jam will use separate 'strip' invocation.
    +        toolset.flags $(toolset).link RPATH $(condition) :  : unchecked ;
    +        toolset.flags $(toolset).link RPATH_LINK $(condition) :  : unchecked ;
    +        }
    +
         case gnu :
             {
             # Strip the binary when no debugging is needed. We use --strip-all flag
             # as opposed to -s since icc (intel's compiler) is generally
             # option-compatible with and inherits from the gcc toolset, but does not
             # support -s.
    -        flags $(toolset).link OPTIONS     $(condition)/off : -Wl,--strip-all   : unchecked ;
    -        flags $(toolset).link RPATH       $(condition)                    :         : unchecked ;
    -        flags $(toolset).link RPATH_LINK  $(condition)                    :        : unchecked ;
    -        flags $(toolset).link START-GROUP $(condition)                    : -Wl,--start-group : unchecked ;
    -        flags $(toolset).link END-GROUP   $(condition)                    : -Wl,--end-group   : unchecked ;
    +        toolset.flags $(toolset).link OPTIONS     $(condition)/off : -Wl,--strip-all   : unchecked ;
    +        toolset.flags $(toolset).link RPATH       $(condition)                    :         : unchecked ;
    +        toolset.flags $(toolset).link RPATH_LINK  $(condition)                    :        : unchecked ;
    +        toolset.flags $(toolset).link START-GROUP $(condition)                    : -Wl,--start-group : unchecked ;
    +        toolset.flags $(toolset).link END-GROUP   $(condition)                    : -Wl,--end-group   : unchecked ;
     
             # gnu ld has the ability to change the search behaviour for libraries
             # referenced by -l switch. These modifiers are -Bstatic and -Bdynamic
    @@ -554,49 +636,52 @@ rule init-link-flags ( toolset linker condition )
             # search patterns!
     
             # On *nix mixing shared libs with static runtime is not a good idea.
    -        flags $(toolset).link FINDLIBS-ST-PFX $(condition)/shared
    +        toolset.flags $(toolset).link FINDLIBS-ST-PFX $(condition)/shared
                 : -Wl,-Bstatic : unchecked ;
    -        flags $(toolset).link FINDLIBS-SA-PFX $(condition)/shared
    +        toolset.flags $(toolset).link FINDLIBS-SA-PFX $(condition)/shared
                 : -Wl,-Bdynamic : unchecked ;
     
             # On windows allow mixing of static and dynamic libs with static
             # runtime.
    -        flags $(toolset).link FINDLIBS-ST-PFX $(condition)/static/windows
    +        toolset.flags $(toolset).link FINDLIBS-ST-PFX $(condition)/static/windows
                 : -Wl,-Bstatic : unchecked ;
    -        flags $(toolset).link FINDLIBS-SA-PFX $(condition)/static/windows
    +        toolset.flags $(toolset).link FINDLIBS-SA-PFX $(condition)/static/windows
                 : -Wl,-Bdynamic : unchecked ;
    -        flags $(toolset).link OPTIONS $(condition)/static/windows
    +        toolset.flags $(toolset).link OPTIONS $(condition)/static/windows
                 : -Wl,-Bstatic : unchecked ;
             }
     
    -    case darwin :
    +    case hpux :
             {
    -        # On Darwin, the -s option to ld does not work unless we pass -static,
    -        # and passing -static unconditionally is a bad idea. So, don't pass -s.
    -        # at all, darwin.jam will use separate 'strip' invocation.
    -        flags $(toolset).link RPATH $(condition) :  : unchecked ;
    -        flags $(toolset).link RPATH_LINK $(condition) :  : unchecked ;
    +        toolset.flags $(toolset).link OPTIONS $(condition)/off
    +            : -Wl,-s : unchecked ;
    +        toolset.flags $(toolset).link OPTIONS $(condition)/shared
    +            : -fPIC : unchecked ;
             }
     
         case osf :
             {
    -            # No --strip-all, just -s.
    -            flags $(toolset).link OPTIONS $(condition)/off : -Wl,-s
    -              : unchecked ;
    -            flags $(toolset).link RPATH $(condition) :  : unchecked ;
    -            # This does not supports -R.
    -            flags $(toolset).link RPATH_OPTION $(condition) : -rpath : unchecked ;
    -            # -rpath-link is not supported at all.
    +        # No --strip-all, just -s.
    +        toolset.flags $(toolset).link OPTIONS $(condition)/off
    +            : -Wl,-s : unchecked ;
    +        toolset.flags $(toolset).link RPATH $(condition) : 
    +            : unchecked ;
    +        # This does not supports -R.
    +        toolset.flags $(toolset).link RPATH_OPTION $(condition) : -rpath
    +            : unchecked ;
    +        # -rpath-link is not supported at all.
             }
     
         case sun :
             {
    -        flags $(toolset).link OPTIONS $(condition)/off : -Wl,-s
    +        toolset.flags $(toolset).link OPTIONS $(condition)/off
    +            : -Wl,-s : unchecked ;
    +        toolset.flags $(toolset).link RPATH $(condition) : 
                 : unchecked ;
    -        flags $(toolset).link RPATH $(condition) :  : unchecked ;
             # Solaris linker does not have a separate -rpath-link, but allows to use
             # -L for the same purpose.
    -        flags $(toolset).link LINKPATH $(condition) :  : unchecked ;
    +        toolset.flags $(toolset).link LINKPATH $(condition) : 
    +            : unchecked ;
     
             # This permits shared libraries with non-PIC code on Solaris.
             # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the
    @@ -604,51 +689,16 @@ rule init-link-flags ( toolset linker condition )
             # separate question.
             # AH, 2004/10/16: it is still necessary because some tests link against
             # static libraries that were compiled without PIC.
    -        flags $(toolset).link OPTIONS $(condition)/shared : -mimpure-text
    -            : unchecked ;
    +        toolset.flags $(toolset).link OPTIONS $(condition)/shared
    +            : -mimpure-text : unchecked ;
             }
     
    -    case hpux :
    -        {
    -            flags $(toolset).link OPTIONS $(condition)/off
    -                : -Wl,-s : unchecked ;
    -            flags $(toolset).link OPTIONS $(condition)/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 * :
             {
    -            errors.user-error
    +        errors.user-error
                 "$(toolset) initialization: invalid linker '$(linker)'" :
                 "The value '$(linker)' specified for  is not recognized." :
    -            "Possible values are 'gnu', 'darwin', 'osf', 'hpux' or 'sun'" ;
    +            "Possible values are 'aix', 'darwin', 'gnu', 'hpux', 'osf' or 'sun'" ;
             }
         }
     }
    @@ -656,6 +706,7 @@ rule init-link-flags ( toolset linker condition )
     # Declare actions for linking.
     rule link ( targets * : sources * : properties * )
     {
    +    setup-threading $(targets) : $(sources) : $(properties) ;
         SPACE on $(targets) = " " ;
         # Serialize execution of the 'link' action, since running N links in
         # parallel is just slower. For now, serialize only gcc links, it might be a
    @@ -675,11 +726,11 @@ actions link bind LIBRARIES
     # always available.
     .AR = ar ;
     
    -flags gcc.archive AROPTIONS  ;
    +toolset.flags gcc.archive AROPTIONS  ;
     
     rule archive ( targets * : sources * : properties * )
     {
    -    # Always remove archive and start again. Here's rationale from
    +    # Always remove archive and start again. Here is the rationale from
         #
         # Andre Hentz:
         #
    @@ -719,72 +770,86 @@ actions piecemeal archive
     
     rule link.dll ( targets * : sources * : properties * )
     {
    +    setup-threading $(targets) : $(sources) : $(properties) ;
         SPACE on $(targets) = " " ;
         JAM_SEMAPHORE on $(targets) = gcc-link-semaphore ;
     }
     
    -# Differ from 'link' above only by -shared.
    +# Differs from 'link' above only by -shared.
     actions link.dll bind LIBRARIES
     {
         "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" "$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS)
     }
     
    -# Set up threading support. It's somewhat contrived, so perform it at the end,
    -# to avoid cluttering other code.
    -
    -if [ os.on-windows ]
    +rule setup-threading ( targets * : sources * : properties * )
     {
    -    flags gcc OPTIONS multi : -mthreads ;
    -}
    -else if [ modules.peek : UNIX ]
    -{
    -    switch [ modules.peek : JAMUNAME ]
    -    {
    -    case SunOS* :
    +    local threading = [ feature.get-values threading : $(properties) ] ;
    +    if $(threading) = multi
    +    {        
    +        local target = [ feature.get-values target-os : $(properties) ] ;
    +        local option ;
    +        local libs ;
    +        
    +        switch $(target)
             {
    -        flags gcc OPTIONS multi : -pthreads ;
    -        flags gcc FINDLIBS-SA : rt ;
    +            case windows :
    +            {
    +                option = -mthreads ;
    +            }
    +            case cygwin :
    +            {
    +                option = -mthreads ;
    +            }
    +            case sunos :
    +            {
    +                option = -pthreads ;
    +                libs = rt ;
    +            }
    +            case beos :
    +            {            
    +                # BeOS has no threading options, so do not set anything here.
    +            }        
    +            case *bsd :
    +            {
    +                option = -pthread ;
    +                # There is no -lrt on BSD.
    +            }
    +            case sgi :
    +            {
    +                # gcc on IRIX does not support multi-threading so do not set anything
    +                # here.
    +            }
    +            case darwin :
    +            {
    +                # Darwin has no threading options so do not set anything here.
    +            }
    +            case * :
    +            {
    +                option = -pthread ;
    +                libs = rt ;
    +            }
             }
    -    case BeOS :
    +    
    +        if $(option)
             {
    -        # BeOS has no threading options, don't set anything here.
    +            OPTIONS on $(targets) += $(option) ;
             }
    -    case *BSD :
    +        if $(libs)
             {
    -        flags gcc OPTIONS multi : -pthread ;
    -        # there is no -lrt on BSD
    +            FINDLIBS-SA on $(targets) += $(libs) ;
             }
    -    case DragonFly :
    -        {
    -        flags gcc OPTIONS multi : -pthread ;
    -        # there is no -lrt on BSD - DragonFly is a FreeBSD variant,
    -        # which anoyingly doesn't say it's a *BSD.
    -        }
    -    case IRIX :
    -        {
    -        # gcc on IRIX does not support multi-threading, don't set anything here.
    -        }
    -    case Darwin :
    -        {
    -        # Darwin has no threading options, don't set anything here.
    -        }
    -    case * :
    -        {
    -        flags gcc OPTIONS multi : -pthread ;
    -        flags gcc FINDLIBS-SA : rt ;
    -        }
    -    }
    +    }    
     }
     
     local rule cpu-flags ( toolset variable : architecture : instruction-set + : values + : default ? )
     {
         if $(default)
         {
    -        flags $(toolset) $(variable)
    +        toolset.flags $(toolset) $(variable)
                 $(architecture)/
                 : $(values) ;
         }
    -    flags $(toolset) $(variable)
    +    toolset.flags $(toolset) $(variable)
             /$(instruction-set)
             $(architecture)/$(instruction-set)
             : $(values) ;
    @@ -793,8 +858,8 @@ local rule cpu-flags ( toolset variable : architecture : instruction-set + : val
     # Set architecture/instruction-set options.
     #
     # x86 and compatible
    -flags gcc OPTIONS x86/32 : -m32 ;
    -flags gcc OPTIONS x86/64 : -m64 ;
    +toolset.flags gcc OPTIONS x86/32 : -m32 ;
    +toolset.flags gcc OPTIONS x86/64 : -m64 ;
     cpu-flags gcc OPTIONS : x86 : i386 : -march=i386 : default ;
     cpu-flags gcc OPTIONS : x86 : i486 : -march=i486 ;
     cpu-flags gcc OPTIONS : x86 : i586 : -march=i586 ;
    @@ -828,8 +893,8 @@ cpu-flags gcc OPTIONS : x86 : winchip2 : -march=winchip2 ;
     cpu-flags gcc OPTIONS : x86 : c3 : -march=c3 ;
     cpu-flags gcc OPTIONS : x86 : c3-2 : -march=c3-2 ;
     # Sparc
    -flags gcc OPTIONS sparc/32 : -m32 ;
    -flags gcc OPTIONS sparc/64 : -m64 ;
    +toolset.flags gcc OPTIONS sparc/32 : -m32 ;
    +toolset.flags gcc OPTIONS sparc/64 : -m64 ;
     cpu-flags gcc OPTIONS : sparc : c3 : -mcpu=c3 : default ;
     cpu-flags gcc OPTIONS : sparc : v7 : -mcpu=v7 ;
     cpu-flags gcc OPTIONS : sparc : cypress : -mcpu=cypress ;
    @@ -846,8 +911,8 @@ cpu-flags gcc OPTIONS : sparc : v9 : -mcpu=v9 ;
     cpu-flags gcc OPTIONS : sparc : ultrasparc : -mcpu=ultrasparc ;
     cpu-flags gcc OPTIONS : sparc : ultrasparc3 : -mcpu=ultrasparc3 ;
     # RS/6000 & PowerPC
    -flags gcc OPTIONS power/32 : -m32 ;
    -flags gcc OPTIONS power/64 : -m64 ;
    +toolset.flags gcc OPTIONS power/32 : -m32 ;
    +toolset.flags gcc OPTIONS power/64 : -m64 ;
     cpu-flags gcc OPTIONS : power : 403 : -mcpu=403 ;
     cpu-flags gcc OPTIONS : power : 505 : -mcpu=505 ;
     cpu-flags gcc OPTIONS : power : 601 : -mcpu=601 ;
    @@ -881,6 +946,6 @@ cpu-flags gcc OPTIONS : power : rios2 : -mcpu=rios2 ;
     cpu-flags gcc OPTIONS : power : rsc : -mcpu=rsc ;
     cpu-flags gcc OPTIONS : power : rs64a : -mcpu=rs64 ;
     # AIX variant of RS/6000 & PowerPC
    -flags gcc OPTIONS power/32/aix : -maix32 ;
    -flags gcc OPTIONS power/64/aix : -maix64 ;
    -flags gcc AROPTIONS power/64/aix : "-X 64" ;
    +toolset.flags gcc OPTIONS power/32/aix : -maix32 ;
    +toolset.flags gcc OPTIONS power/64/aix : -maix64 ;
    +toolset.flags gcc AROPTIONS power/64/aix : "-X 64" ;
    diff --git a/v2/tools/generate.jam b/v2/tools/generate.jam
    index 588077348..6732fa355 100644
    --- a/v2/tools/generate.jam
    +++ b/v2/tools/generate.jam
    @@ -2,18 +2,17 @@
     # 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)
     
    -# Declares main target 'generate' that can be used to produce targets
    -# by calling a user-provides rule, that takes virtual target and produces
    -# virtual target.
    +# Declares main target 'generate' used to produce targets by calling a
    +# user-provided rule that takes and produces virtual targets.
     
    -import targets ;
     import "class" : new ;
    -import property ;
     import errors ;
    -import regex ;
    -import property-set ;
    -import project ;
     import feature ;
    +import project ;
    +import property ;
    +import property-set ;
    +import targets ;
    +import regex ;
     
     
     feature.feature generating-rule : : free ;
    @@ -31,11 +30,10 @@ class generated-target-class : basic-target
             basic-target.__init__ $(name) : $(project) : $(sources)
                 : $(requirements) : $(default-build) : $(usage-requirements) ;
     
    -        local r = [ $(self.requirements).get  ] ;
    -        if ! $(r)
    +        if ! [ $(self.requirements).get  ]
             {
    -            errors.user-error
    -                "The generate rule requires  property to be set" ;
    +            errors.user-error "The generate rule requires the "
    +                "property to be set" ;
             }
         }
     
    @@ -44,14 +42,16 @@ class generated-target-class : basic-target
             local result ;
             local gr = [ $(property-set).get  ] ;
     
    -        # FIXME: this is copy-paste from virtual-target.jam. Must
    -        # have n utilty rule to call a rule like this.
    +        # FIXME: this is a copy-paste from virtual-target.jam. We should add a
    +        # utility rule to call a rule like this.
             local rule-name = [ MATCH ^@(.*) : $(gr) ] ;
             if $(rule-name)
             {
    -            if $(tag[2])
    +            if $(gr[2])
                 {
    -                errors.error "@rulename is present but is not the only  feature" ;
    +                local target-name = [ full-name ] ;
    +                errors.user-error "Multiple  properties"
    +                    "encountered for target $(target-name)." ;
                 }
     
                 result = [ indirect.call $(rule-name) $(self.project) $(name)
    @@ -79,8 +79,10 @@ class generated-target-class : basic-target
                     targets = $(result) ;
                 }
             }
    +        # FIXME: the following loop should be doable using sequence.transform or
    +        # some similar utility rule.
             local rt ;
    -        for t in $(targets)
    +        for local t in $(targets)
             {
                 rt += [ virtual-target.register $(t) ] ;
             }
    diff --git a/v2/tools/hp_cxx.jam b/v2/tools/hp_cxx.jam
    index 515076342..86cd783e2 100644
    --- a/v2/tools/hp_cxx.jam
    +++ b/v2/tools/hp_cxx.jam
    @@ -124,6 +124,8 @@ flags hp_cxx.link LIBRARIES  ;
     flags hp_cxx.link FINDLIBS-ST  ;
     flags hp_cxx.link FINDLIBS-SA  ;
     
    +flags hp_cxx.compile.c++ TEMPLATE_DEPTH  ;
    +
     actions link bind LIBRARIES
     {
         $(CONFIG_COMMAND) -noimplicit_include $(OPTIONS) -o "$(<)" -L$(LIBPATH) "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) -lrt -lm
    @@ -154,9 +156,20 @@ actions compile.c
     # Note: We deliberately don't suppress any warnings on the compiler command
     # line, the user can always do this in a customized toolset later on.
     
    +rule compile.c++
    +{
    +    # We preprocess the TEMPLATE_DEPTH command line option here because we found
    +    # no way to do it correctly in the actual action code. There we either get
    +    # the -pending_instantiations parameter when no c++-template-depth property
    +    # has been specified or we get additional quotes around
    +    # "-pending_instantiations ".
    +    local template-depth = [ on $(1) return $(TEMPLATE_DEPTH) ] ;
    +    TEMPLATE_DEPTH on $(1) = "-pending_instantiations "$(template-depth) ;
    +}
    +
     actions compile.c++
     {
    -    $(CONFIG_COMMAND) -x cxx -c -std strict_ansi -nopure_cname -noimplicit_include -timplicit_local -ptr "$(<[1]:D)/cxx_repository" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -o "$(<)" "$(>)"
    +    $(CONFIG_COMMAND) -x cxx -c -std strict_ansi -nopure_cname -noimplicit_include -timplicit_local -ptr "$(<[1]:D)/cxx_repository" $(OPTIONS) $(TEMPLATE_DEPTH) -D$(DEFINES) -I"$(INCLUDES)" -o "$(<)" "$(>)"
     }
     
     # Always create archive from scratch. See the gcc toolet for rationale.
    diff --git a/v2/tools/intel-win.jam b/v2/tools/intel-win.jam
    index a4f78b79d..7cefdbe5d 100644
    --- a/v2/tools/intel-win.jam
    +++ b/v2/tools/intel-win.jam
    @@ -3,21 +3,19 @@
     # (See accompanying file LICENSE_1_0.txt
     # or copy at http://www.boost.org/LICENSE_1_0.txt)
     
    -import toolset ;
    -import feature ;
    -import toolset : flags ;
    -import os ;
    -import errors ;
    -
    -# This is needed because the rule we import here depend on 'common'
    -# That's nasty.
    +# Importing common is needed because the rules we inherit here depend on it.
    +# That is nasty.
     import common ;
    -
    +import errors ;
    +import feature ;
     import intel ;
    +import msvc ;
    +import os ;
    +import toolset ;
    +
     
     feature.extend-subfeature toolset intel : platform : win ;
     
    -import msvc ;
     toolset.inherit-generators intel-win intel win : msvc ;
     toolset.inherit-flags intel-win : msvc ;
     toolset.inherit-rules intel-win : msvc ;
    @@ -31,28 +29,28 @@ rule init ( version ? :     # the compiler version
                                 # either 'vc6', 'vc7', 'vc7.1'
                                 # or 'native'(default).
               )
    -{           
    -    local compatibility = 
    +{
    +    local compatibility =
           [ feature.get-values  : $(options) ] ;
         local condition = [  common.check-init-parameters intel-win
             : version $(version) : compatibility $(compatibility) ] ;
    -    
    +
         command = [ common.get-invocation-command intel-win : icl.exe :
    -        $(command) ] ;    
    -    
    +        $(command) ] ;
    +
         common.handle-options intel-win : $(condition) : $(command) : $(options) ;
    -   
    +
         local root ;
         if $(command)
         {
             root = [ common.get-absolute-tool-path $(command[-1]) ] ;
             root = $(root)/ ;
         }
    -    
    +
         local setup ;
         setup = $(root)/iclvars.bat ;
         setup = "call \""$(setup)"\" > nul " ;
    -        
    +
         if [ os.name ] = NT
         {
             setup = $(setup)"
    @@ -62,52 +60,51 @@ rule init ( version ? :     # the compiler version
         {
             setup = "cmd /S /C "$(setup)" \"&&\" " ;
         }
    -    
    -    
    -    flags intel-win.compile .CC $(condition) : $(setup)icl ; 
    -    flags intel-win.link .LD $(condition) : $(setup)xilink ; 
    -    flags intel-win.archive .LD $(condition) : $(setup)xilink /lib ;       
    -    flags intel-win.link .MT $(condition) : mt -nologo ;
    -    
    +
    +    toolset.flags intel-win.compile .CC $(condition) : $(setup)icl ;
    +    toolset.flags intel-win.link .LD $(condition) : $(setup)xilink ;
    +    toolset.flags intel-win.archive .LD $(condition) : $(setup)xilink /lib ;
    +    toolset.flags intel-win.link .MT $(condition) : mt -nologo ;
    +
         local m = [ MATCH (.).* : $(version) ] ;
         local major = $(m[1]) ;
     
         local C++FLAGS ;
    -    
    +
         C++FLAGS += /nologo ;
    -    
    +
         # Reduce the number of spurious error messages
         C++FLAGS += /Qwn5 /Qwd985 ;
     
         # Enable ADL
         C++FLAGS += -Qoption,c,--arg_dep_lookup ; #"c" works for C++, too
    -    
    -    # Disable Microsoft "secure" overloads in Dinkumware libraries
    -    # since they cause compile errors with Intel versions 9 and 10    
    +
    +    # Disable Microsoft "secure" overloads in Dinkumware libraries since they
    +    # cause compile errors with Intel versions 9 and 10.
         C++FLAGS += -D_SECURE_SCL=0 ;
     
         if $(major) > 5
         {
    -        C++FLAGS += /Zc:forScope ;  # Add support for correct for loop scoping
    +        C++FLAGS += /Zc:forScope ;  # Add support for correct for loop scoping.
         }
     
    -    # Add options recognized only by intel7
    +    # Add options recognized only by intel7 and above.
         if $(major) >= 7
         {
             C++FLAGS += /Qansi_alias ;
         }
    -    
    +
         if $(compatibility) = vc6
         {
    -        C++FLAGS += 
    +        C++FLAGS +=
               # Emulate VC6
               /Qvc6
    -      
    -          # no wchar_t support in vc6 dinkum library.  Furthermore, in vc6
    +
    +          # No wchar_t support in vc6 dinkum library.  Furthermore, in vc6
               # compatibility-mode, wchar_t is not a distinct type from unsigned
    -          # short
    +          # short.
               -DBOOST_NO_INTRINSIC_WCHAR_T
    -          ; 
    +          ;
         }
         else
         {
    @@ -119,21 +116,19 @@ rule init ( version ? :     # the compiler version
                   -D_NATIVE_WCHAR_T_DEFINED
                   ;
             }
    -    }        
    -    
    -    
    +    }
    +
         if $(compatibility) && $(compatibility) != native
    -    {        
    +    {
             C++FLAGS += /Q$(base-vc) ;
         }
    -    else        
    +    else
         {
    -        C++FLAGS += 
    +        C++FLAGS +=
               -Qoption,cpp,--arg_dep_lookup
    -          # The following options were intended to disable
    -          # 'bug-emulation' mode of intel compiler, but later
    -          # were reported to case ICE with Intel-Win 9.0
    -          # It's not yet clear which options can be safely used.
    +          # The following options were intended to disable the Intel compiler's
    +          # 'bug-emulation' mode, but were later reported to be causing ICE with
    +          # Intel-Win 9.0. It is not yet clear which options can be safely used.
               # -Qoption,cpp,--const_string_literals
               # -Qoption,cpp,--new_for_init
               # -Qoption,cpp,--no_implicit_typename
    @@ -141,28 +136,26 @@ rule init ( version ? :     # the compiler version
               # -Qoption,cpp,--no_microsoft_bugs
               ;
         }
    -    
    -    flags intel-win CFLAGS $(condition) : $(C++FLAGS) ;
    -    
    +
    +    toolset.flags intel-win CFLAGS $(condition) : $(C++FLAGS) ;
    +
         if ! $(compatibility)
         {
             # If there's no backend version, assume 7.1.
             compatibility = vc7.1 ;
         }
    -    
    +
         local extract-version = [ MATCH ^vc(.*) : $(compatibility) ] ;
         if ! $(extract-version)
         {
             errors.user-error "Invalid value for compatibility option:"
    -          $(compatibility) ;
    +            $(compatibility) ;
         }
    -    
    +
         # Depending on the settings, running of tests require some runtime DLLs.
    -    flags intel-win RUN_PATH $(condition) : $(root) ;
    -    
    +    toolset.flags intel-win RUN_PATH $(condition) : $(root) ;
    +
         msvc.configure-version-specific intel-win : $(extract-version[1]) : $(condition) ;
     }
     
    -flags intel-win.link LIBRARY_OPTION intel : "" ;
    -
    -
    +toolset.flags intel-win.link LIBRARY_OPTION intel : "" ;
    diff --git a/v2/tools/make.jam b/v2/tools/make.jam
    index c582ad67f..085672857 100644
    --- a/v2/tools/make.jam
    +++ b/v2/tools/make.jam
    @@ -7,14 +7,13 @@
     
     #  This module defines the 'make' main target rule.
     
    -import targets ;
     import "class" : new ;
    -import property ;
     import errors : error ;
    -import type : type ;
    -import regex ;
    -import property-set ;
     import project ;
    +import property ;
    +import property-set ;
    +import regex ;
    +import targets ;
     
     
     class make-target-class : basic-target
    @@ -25,19 +24,20 @@ class make-target-class : basic-target
         rule __init__ ( name : project : sources * : requirements *
             : default-build * : usage-requirements * )
         {
    -        basic-target.__init__ $(name) : $(project) : $(sources)
    -          : $(requirements) : $(default-build) : $(usage-requirements) ;
    +        basic-target.__init__ $(name) : $(project) : $(sources) :
    +            $(requirements) : $(default-build) : $(usage-requirements) ;
         }
     
         rule construct ( name : source-targets * : property-set )
         {
             local action-name = [ $(property-set).get  ] ;
    -        # 'm' will always be set -- we add '@' ourselves in 'make' rule below.
    +        # 'm' will always be set -- we add '@' ourselves in the '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 t = [ new file-target $(self.name) exact : [ type.type
    +            $(self.name) ] : $(self.project) : $(a) ] ;
             return [ property-set.empty ] [ virtual-target.register $(t) ] ;
         }
     }
    @@ -45,8 +45,8 @@ class make-target-class : basic-target
     
     # Declares the 'make' main target.
     #
    -rule make ( target-name : sources * : generating-rule + : requirements *
    -    : usage-requirements * )
    +rule make ( target-name : sources * : generating-rule + : requirements * :
    +    usage-requirements * )
     {
         local project = [ project.current ] ;
     
    @@ -64,8 +64,9 @@ rule make ( target-name : sources * : generating-rule + : requirements *
                 : [ 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) ]
    -     ] ;
    +            : [ targets.main-target-usage-requirements $(usage-requirements) :
    +                $(project) ] ] ;
     }
     
    +
     IMPORT $(__name__) : make : : make ;
    diff --git a/v2/tools/message.jam b/v2/tools/message.jam
    new file mode 100644
    index 000000000..212d8542c
    --- /dev/null
    +++ b/v2/tools/message.jam
    @@ -0,0 +1,55 @@
    +# Copyright 2008 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)
    +
    +# Defines main target type 'message', that prints a message when built for the
    +# first time.
    +
    +import project ;
    +import "class" : new ;
    +import targets ;
    +import property-set ;
    +
    +class message-target-class : basic-target
    +{
    +    rule __init__ ( name-and-dir : project : * )
    +    {
    +        basic-target.__init__ $(name-and-dir) : $(project) ;
    +        self.3 = $(3) ;
    +        self.4 = $(4) ;
    +        self.5 = $(5) ;
    +        self.6 = $(6) ;
    +        self.7 = $(7) ;
    +        self.8 = $(8) ;        
    +        self.9 = $(9) ;        
    +        self.built = ;
    +    }
    +    
    +    rule construct ( name : source-targets * : property-set )
    +    {
    +        if ! $(self.built)
    +        {
    +            for i in 3 4 5 6 7 8 9
    +            {
    +                if $(self.$(i))
    +                {
    +                    ECHO $(self.$(i)) ;
    +                }
    +            }
    +            self.built = 1 ;
    +        }
    +        
    +        return [ property-set.empty ] ;
    +    }
    +}
    +
    +
    +rule message ( name : * )
    +{
    +    local project = [ project.current ] ;
    +
    +    targets.main-target-alternative
    +      [ new message-target-class $(name) : $(project) 
    +        : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) ] ;
    +}
    +IMPORT $(__name__) : message : : message ;
    \ No newline at end of file
    diff --git a/v2/tools/msvc.jam b/v2/tools/msvc.jam
    index 7d056aa81..727f09633 100644
    --- a/v2/tools/msvc.jam
    +++ b/v2/tools/msvc.jam
    @@ -4,75 +4,64 @@
     # Copyright (c) 2006 Bojan Resnik.
     # Copyright (c) 2006 Ilya Sokolov.
     # Copyright (c) 2007 Rene Rivera
    +# Copyright (c) 2008 Jurko Gospodnetic
     #
     # Use, modification and distribution is subject to the Boost Software
     # License Version 1.0. (See accompanying file LICENSE_1_0.txt or
     # http://www.boost.org/LICENSE_1_0.txt)
     
    +################################################################################
    +#
    +# MSVC Boost Build toolset module.
    +# --------------------------------
    +#
    +# All toolset versions need to have their location either auto-detected or
    +# explicitly specified except for the special 'default' version that expects the
    +# environment to find the needed tools or report an error.
    +#
    +################################################################################
    +
     import "class" : new ;
    -import property ;
    -import generators ;
    -import os ;
    -import type ;
    -import toolset : flags ;
    +import common ;
     import errors ;
     import feature ;
    -import path ;
    -import common ;
    -import rc ;
    -import midl ;
    +import generators ;
     import mc ;
    +import midl ;
    +import os ;
    +import path ;
     import pch ;
    -
    -if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
    -{
    -    .debug-configuration = true ;
    -}
    -
    -feature.extend toolset : msvc ;
    -
    -feature.subfeature toolset msvc : vendor
    -  : intel
    -  : propagated optional
    -  # intel and msvc supposedly have link-compatible objects... remains
    -  # to be seen, though ;-)
    -  ;
    -
    -# List of all registered configurations
    -.versions = [ new configurations ] ;
    -
    -# Inherit MIDL flags
    -toolset.inherit-flags msvc : midl ;
    -
    -# Inherit MC flags
    -toolset.inherit-flags msvc : mc ;
    -
    -# Dynamic runtime comes only in MT flavour.
    -toolset.add-requirements msvc,shared:multi ;
    -
    -RM = [ common.rm-command ] ;
    -nl = "
    -" ;
    +import property ;
    +import rc ;
    +import toolset ;
    +import type ;
     
     
    -# Initialize the toolset for a specific version. As the result, path to compiler
    -# and, possible, program names are set up, and will be used when that version of
    -# compiler is requested. For example, you might have:
    +################################################################################
    +#
    +# Public rules.
    +#
    +################################################################################
    +
    +# Initialize a specific toolset version configuration. As the result, path to
    +# compiler and, possible, program names are set up, and will be used when that
    +# version of compiler is requested. For example, you might have:
     #
     #    using msvc : 6.5 : cl.exe ;
     #    using msvc : 7.0 : Y:/foo/bar/cl.exe ;
     #
    -# The version paramater can be ommited:
    +# The version parameter may be ommited:
     #
     #    using msvc : : Z:/foo/bar/cl.exe ;
     #
    -# Two special version keywords may be supplied:
    -#   - all - all detected versions will be registered;
    +# The following keywords have special meanings when specified as versions:
    +#   - all     - all detected but not yet used versions will be marked as used
    +#               with their default options.
     #   - default - this is an equivalent to an empty version.
     #
     # Depending on a supplied version, detected configurations and presence 'cl.exe'
     # in the path different results may be achieved. The following table describes
    -# all possible cases:
    +# the possible scenarios:
     #
     #                                      Nothing            "x.y"
     # Passed   Nothing       "x.y"         detected,          detected,
    @@ -86,8 +75,9 @@ nl = "
     # "x.y" - refers to a detected version;
     # "a.b" - refers to an undetected version.
     #
    -# Note: for free VC7.1 tools, we do not correctly find vcvars32.bar when user
    -# explicitly provides a path.
    +# FIXME: Currently the command parameter and the  property parameter
    +# seem to overlap in duties. Remove this duplication. This seems to be related
    +# to why someone started preparing to replace init with configure rules.
     #
     rule init (
         # The msvc version being configured. When omitted the tools invoked when no
    @@ -141,28 +131,47 @@ rule init (
         {
             options += $(command) ;
         }
    -
         configure $(version) : $(options) ;
     }
     
     
     # 'configure' is a newer version of 'init'. The parameter 'command' is passed as
    -# a part of the 'options' list.
    +# a part of the 'options' list. See the 'init' rule comment for more detailed
    +# information.
     #
     rule configure ( version ? : options * )
     {
         switch $(version)
         {
    -        case all :
    +        case "all" :
                 if $(options)
                 {
    -                errors.error "msvc: options should be empty when 'all' is specified" ;
    +                errors.error "MSVC toolset configuration: options should be"
    +                    "empty when '$(version)' is specified." ;
                 }
     
    -            # Use all detected versions.
    -            for local v in [ $(.versions).all ]
    +            # Configure (i.e. mark as used) all registered versions.
    +            local all-versions = [ $(.versions).all ] ;
    +            if ! $(all-versions)
                 {
    -                configure-really $(v) ;
    +                if $(.debug-configuration)
    +                {
    +                    ECHO "notice: [msvc-cfg] Asked to configure all registered"
    +                        "msvc toolset versions when there are none currently"
    +                        "registered." ;
    +                }
    +            }
    +            else
    +            {
    +                for local v in $(all-versions)
    +                {
    +                    # Note that there is no need to skip already configured
    +                    # versions here as this will request configure-really rule
    +                    # to configure the version using default options which will
    +                    # in turn cause it to simply do nothing in case the version
    +                    # has already been configured.
    +                    configure-really $(v) ;
    +                }
                 }
     
             case "default" :
    @@ -174,67 +183,439 @@ rule configure ( version ? : options * )
     }
     
     
    -# Supported CPU architectures.
    -.cpu-arch-i386 =
    -    /
    -    /32
    -    x86/
    -    x86/32 ;
    -
    -.cpu-arch-amd64 =
    -    /64
    -    x86/64 ;
    -
    -.cpu-arch-ia64 =
    -    ia64/
    -    ia64/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.
    +# Sets up flag definitions dependent on the compiler version used.
    +# - 'version' is the version of compiler in N.M format.
    +# - '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.
     #
    -local rule locate-default-setup ( command : parent : setup-name )
    +rule configure-version-specific ( toolset : version : conditions )
     {
    -    local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
    -    if $(result[1])
    +    toolset.push-checking-for-flags-module unchecked ;
    +    # Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
    +    # /Zc:wchar_t options that improve C++ standard conformance, but those
    +    # options are off by default. If we are sure that the msvc version is at
    +    # 7.*, add those options explicitly. We can be sure either if user specified
    +    # version 7.* explicitly or if we auto-detected the version ourselves.
    +    if ! [ MATCH ^(6\\.) : $(version) ]
         {
    -        return $(result[1]) ;
    +        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)/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)/all : /Wp64 ;
    +        }
    +    }
    +
    +    #
    +    # Processor-specific optimization.
    +    #
    +
    +    if [ MATCH ^([67]) : $(version) ]
    +    {
    +        # 8.0 deprecates some of the options.
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/speed $(conditions)/space : /Ogiy /Gs ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/speed : /Ot ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/space : /Os ;
    +
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/ : /GB ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/i386 : /G3 ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/i486 : /G4 ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/$(.cpu-type-g5) : /G5 ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/$(.cpu-type-g6) : /G6 ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/$(.cpu-type-g7) : /G7 ;
    +
    +        # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
    +        # tests will fail.
    +        toolset.flags $(toolset).compile CFLAGS $(conditions) : /Op ;
    +
    +        # 7.1 and below have single-threaded static RTL.
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/off/static/single : /ML ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/on/static/single : /MLd ;
    +    }
    +    else
    +    {
    +        # 8.0 and above adds some more options.
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/ : /favor:blend ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/$(.cpu-type-em64t) : /favor:EM64T ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/$(.cpu-type-amd64) : /favor:AMD64 ;
    +
    +        # 8.0 and above only has multi-threaded static RTL.
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/off/static/single : /MT ;
    +        toolset.flags $(toolset).compile CFLAGS $(conditions)/on/static/single : /MTd ;
    +    }
    +    toolset.pop-checking-for-flags-module ;
    +}
    +
    +
    +# Registers this toolset including all of its flags, features & generators. Does
    +# nothing on repeated calls.
    +#
    +rule register-toolset ( )
    +{
    +    if ! msvc in [ feature.values toolset ]
    +    {
    +        register-toolset-really ;
         }
     }
     
     
    +# 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.
    +if [ os.name ] in NT
    +{
    +    # The 'DEL' command would issue a message to stdout if the file does not
    +    # exist, so need a check.
    +    actions archive
    +    {
    +        if exist "$(<[1])" DEL "$(<[1])"
    +        $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    +    }
    +}
    +else
    +{
    +    actions archive
    +    {
    +        $(.RM) "$(<[1])"
    +        $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    +    }
    +}
    +
    +
    +# For the assembler the following options are turned on by default:
    +#
    +#   -coff  generate COFF format object file (compatible with cl.exe output)
    +#   -Zp4   align structures to 4 bytes
    +#   -Cp    preserve case of user identifiers
    +#   -Cx    preserve case in publics, externs
    +#
    +actions compile.asm
    +{
    +    $(.ASM) -nologo -c -coff -Zp4 -Cp -Cx $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)"
    +}
    +
    +
    +rule compile.c ( targets + : sources * : properties * )
    +{
    +    C++FLAGS on $(targets[1]) = ;
    +    get-rspline $(targets) : -TC ;
    +    compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
    +}
    +
    +
    +rule compile.c.pch ( targets + : sources * : properties * )
    +{
    +    C++FLAGS on $(targets[1]) = ;
    +    get-rspline $(targets[1]) : -TC ;
    +    get-rspline $(targets[2]) : -TC ;
    +    local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
    +    if $(pch-source)
    +    {
    +        DEPENDS $(<) : $(pch-source) ;
    +        compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
    +    }
    +    else
    +    {
    +        compile-c-c++-pch $(targets) : $(sources) ;
    +    }
    +}
    +
    +
    +# Action for running the C/C++ compiler without using precompiled headers.
    +#
    +actions compile-c-c++
    +{
    +    $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
    +}
    +
    +
    +rule compile-c-c++ ( targets + : sources * )
    +{
    +    DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
    +    DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
    +}
    +
    +
    +# Action for running the C/C++ compiler using precompiled headers. In addition
    +# to whatever else it needs to compile, this action also adds a temporary source
    +# .cpp file used to compile the precompiled headers themselves.
    +#
    +# The global .escaped-double-quote variable is used to avoid messing up Emacs
    +# syntax highlighting in the messy N-quoted code below.
    +#
    +actions compile-c-c++-pch
    +{
    +    $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote))" $(.CC.FILTER)
    +}
    +
    +
    +# Action for running the C/C++ compiler using precompiled headers. An already
    +# built source file for compiling the precompiled headers is expected to be
    +# given as one of the source parameters.
    +#
    +actions compile-c-c++-pch-s
    +{
    +    $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
    +}
    +
    +
    +rule compile.c++ ( targets + : sources * : properties * )
    +{
    +    get-rspline $(targets) : -TP ;
    +    compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
    +}
    +
    +
    +rule compile.c++.pch ( targets + : sources * : properties * )
    +{
    +    get-rspline $(targets[1]) : -TP ;
    +    get-rspline $(targets[2]) : -TP ;
    +    local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
    +    if $(pch-source)
    +    {
    +        DEPENDS $(<) : $(pch-source) ;
    +        compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
    +    }
    +    else
    +    {
    +        compile-c-c++-pch $(targets) : $(sources) ;
    +    }
    +}
    +
    +
    +# See midl.jam for details.
    +#
    +actions compile.idl
    +{
    +    $(.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)"
    +}
    +
    +
    +actions compile.mc
    +{
    +    $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
    +}
    +
    +
    +actions compile.rc
    +{
    +    $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
    +}
    +
    +
    +rule link.dll ( targets + : sources * : properties * )
    +{
    +    DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
    +}
    +
    +
    +# Incremental linking a DLL causes no end of problems: if the actual exports do
    +# not change, the import .lib file is never updated. Therefore, the .lib is
    +# always out-of-date and gets rebuilt every time. I am not sure that incremental
    +# 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
    +# assemblies and Windows native DLLs. The manifests are embedded as resources
    +# and are useful in any PE target (both DLL and EXE).
    +
    +if [ os.name ] in NT
    +{
    +    actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
    +    {
    +        $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    +        if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
    +        if exist "$(<[1]).manifest" (
    +            $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
    +        )
    +    }
    +
    +    actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
    +    {
    +        $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    +        if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
    +        if exist "$(<[1]).manifest" (
    +            $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
    +        )
    +    }
    +}
    +else
    +{
    +    actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
    +    {
    +        $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    +        if test -e "$(<[1]).manifest"; then
    +            $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);1"
    +        fi
    +    }
    +
    +    actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
    +    {
    +        $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    +        if test -e "$(<[1]).manifest"; then
    +            $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2"
    +        fi
    +    }
    +}
    +
    +
    +################################################################################
    +#
    +# Classes.
    +#
    +################################################################################
    +
    +class msvc-pch-generator : pch-generator
    +{
    +    import property-set ;
    +
    +    rule run-pch ( project name ? : property-set : sources * )
    +    {
    +        # Searching for the header and source file in the sources.
    +        local pch-header ;
    +        local pch-source ;
    +        for local s in $(sources)
    +        {
    +            if [ type.is-derived [ $(s).type ] H ]
    +            {
    +                pch-header = $(s) ;
    +            }
    +            else if
    +                [ type.is-derived [ $(s).type ] CPP ] ||
    +                [ type.is-derived [ $(s).type ] C ]
    +            {
    +                pch-source = $(s) ;
    +            }
    +        }
    +
    +        if ! $(pch-header)
    +        {
    +            errors.user-error "can not build pch without pch-header" ;
    +        }
    +
    +        # If we do not have the PCH source - that is fine. We will just create a
    +        # temporary .cpp file in the action.
    +
    +        local generated = [ generator.run $(project) $(name)
    +            : [ property-set.create
    +                # Passing of  is a dirty trick, needed because
    +                # non-composing generators with multiple inputs are subtly
    +                # broken. For more detailed information see:
    +                # https://zigzag.cs.msu.su:7813/boost.build/ticket/111
    +                $(pch-source)
    +                [ $(property-set).raw ] ]
    +            : $(pch-header) ] ;
    +
    +        local pch-file ;
    +        for local g in $(generated)
    +        {
    +            if [ type.is-derived [ $(g).type ] PCH ]
    +            {
    +                pch-file = $(g) ;
    +            }
    +        }
    +
    +        return [ property-set.create $(pch-header)
    +            $(pch-file) ] $(generated) ;
    +    }
    +}
    +
    +
    +################################################################################
    +#
    +# Local rules.
    +#
    +################################################################################
    +
    +# Detects versions listed as '.known-versions' by checking registry information,
    +# environment variables & default paths. Supports both native Windows and
    +# Cygwin.
    +#
    +local rule auto-detect-toolset-versions ( )
    +{
    +    if [ os.name ] in NT CYGWIN
    +    {
    +        # Get installation paths from the registry.
    +        for local i in $(.known-versions)
    +        {
    +            if $(.version-$(i)-reg)
    +            {
    +                local vc-path ;
    +                for local x in "" "Wow6432Node\\"
    +                {
    +                    vc-path += [ W32_GETREG
    +                        "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
    +                        : "ProductDir" ] ;
    +                }
    +
    +                if $(vc-path)
    +                {
    +                    vc-path = [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ;
    +                    register-configuration $(i) : [ path.native $(vc-path[1]) ] ;
    +                }
    +            }
    +        }
    +    }
    +
    +    # Check environment and default installation paths.
    +    for local i in $(.known-versions)
    +    {
    +        if ! $(i) in [ $(.versions).all ]
    +        {
    +            register-configuration $(i) : [ default-path $(i) ] ;
    +        }
    +    }
    +}
    +
    +
    +# Worker rule for toolset version configuration. Takes an explicit version id or
    +# nothing in case it should configure the default toolset version (the first
    +# registered one or a new 'default' one in case no toolset versions have been
    +# registered yet).
    +#
     local rule configure-really ( version ? : options * )
     {
    -    # Note that if no version supplied uses the default configuration condition
    -    # remains versionless.
         local v = $(version) ;
    +
    +    # Decide what the 'default' version is.
         if ! $(v)
         {
    -        # take the first detected version
    +        # Take the first registered (i.e. auto-detected) version.
             version = [ $(.versions).all ] ;
             version = $(version[1]) ;
             v = $(version) ;
     
    -        # Note: 'version' can still be empty at this point if no versions were
    -        # detected.
    +        # Note: 'version' can still be empty at this point if no versions have
    +        # been auto-detected.
             version ?= "default" ;
         }
     
    -    # Version alias -> real version number
    +    # Version alias -> real version number.
         if $(.version-alias-$(version))
         {
             version = $(.version-alias-$(version)) ;
         }
     
    -    # Check whether selected configuration is used already
    +    # Check whether the selected configuration is already in use.
         if $(version) in [ $(.versions).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)' already configured." ;
    +            errors.error "MSVC toolset configuration: Toolset version"
    +                "'$(version)' already configured." ;
             }
         }
         else
    @@ -249,7 +630,8 @@ local rule configure-really ( version ? : options * )
             $(.versions).use $(version) ;
     
             # Generate conditions and save them.
    -        local conditions = [ common.check-init-parameters msvc : version $(v) ] ;
    +        local conditions = [ common.check-init-parameters msvc : version $(v) ]
    +            ;
     
             $(.versions).set $(version) : conditions : $(conditions) ;
     
    @@ -266,6 +648,8 @@ local rule configure-really ( version ? : options * )
             {
                 # Even if version is not explicitly specified, try to detect the
                 # version from the path.
    +            # FIXME: We currently detect both Microsoft Visual Studio 9.0 and
    +            # 9.0express as 9.0 here.
                 if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
                 {
                     version = 9.0 ;
    @@ -278,7 +662,8 @@ local rule configure-really ( version ? : options * )
                 {
                     version = 7.1 ;
                 }
    -            else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" : $(command) ]
    +            else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" :
    +                $(command) ]
                 {
                     version = 7.1toolkit ;
                 }
    @@ -311,10 +696,11 @@ local rule configure-really ( version ? : options * )
                 # 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.
    +            # have only MSVC 7.1 installed, have its executable on the path 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 it is using the msvc-9.0
    +            # toolset version.
                 command = [ common.get-absolute-tool-path $(command[-1]) ] ;
     
                 local parent = [ path.make $(command) ] ;
    @@ -347,7 +733,8 @@ local rule configure-really ( version ? : options * )
                 global-setup = $(global-setup[1]) ;
                 if ! $(below-8.0)
                 {
    -                global-setup ?= [ locate-default-setup $(command) : $(parent) : vcvarsall.bat ] ;
    +                global-setup ?= [ locate-default-setup $(command) : $(parent) :
    +                    vcvarsall.bat ] ;
                 }
     
                 local default-setup-amd64 = vcvarsx86_amd64.bat ;
    @@ -384,7 +771,7 @@ local rule configure-really ( version ? : options * )
                 }
     
                 local setup-prefix = "call " ;
    -            local setup-suffix = " >nul"$(nl) ;
    +            local setup-suffix = " >nul"$(.nl) ;
                 if ! [ os.name ] in NT
                 {
                     setup-prefix = "cmd.exe /S /C call " ;
    @@ -461,7 +848,7 @@ local rule configure-really ( version ? : options * )
                 {
                     for local cpu-condition in $(cpu-conditions)
                     {
    -                    ECHO "msvc: condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ;
    +                    ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ;
                     }
                 }
     
    @@ -487,112 +874,20 @@ local rule configure-really ( version ? : options * )
                     toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
                 }
             }
    +
             # Set version-specific flags.
             configure-version-specific msvc : $(version) : $(conditions) ;
         }
     }
     
     
    -# Supported CPU types (only Itanium optimization options are supported from
    -# VC++ 2005 on). See http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx
    -cpu-type-g5 = i586 pentium pentium-mmx ;
    -cpu-type-g6 =
    -    i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6 k6-2 k6-3
    -    winchip-c6 winchip2 c3 c3-2 ;
    -
    -cpu-type-em64t = prescott nocona
    -    conroe conroe-xe conroe-l allendale mermon mermon-xe kentsfield kentsfield-xe
    -    penryn wolfdale yorksfield nehalem ;
    -cpu-type-amd64 = k8 opteron athlon64 athlon-fx ;
    -
    -cpu-type-g7 =
    -    pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp athlon-mp
    -    $(cpu-type-em64t) $(cpu-type-amd64) ;
    -
    -cpu-type-itanium = itanium itanium1 merced ;
    -cpu-type-itanium2 = itanium2 mckinley ;
    -
    -
    -# Sets up flag definitions dependent on the compiler version used.
    -# - 'version' is the version of compiler in N.M format.
    -# - '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 : conditions )
    -{
    -    toolset.push-checking-for-flags-module unchecked ;
    -    # Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
    -    # /Zc:wchar_t options that improve C++ standard conformance, but those
    -    # options are off by default. If we're sure that msvc version is at 7.*, add
    -    # those options explicitly. We can be sure either if user specified version
    -    # 7.* explicitly, or if the installation path contain 7.* (checked above).
    -    if ! [ MATCH ^(6\\.) : $(version) ]
    -    {
    -        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)/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)/all : /Wp64 ;
    -        }
    -    }
    -
    -    #
    -    # Processor-specific optimization
    -    #
    -
    -    if [ MATCH ^([67]) : $(version) ]
    -    {
    -        # 8.0 deprecates some of the options.
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/speed $(conditions)/space : /Ogiy /Gs ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/speed : /Ot ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/space : /Os ;
    -
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/ : /GB ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/i386 : /G3 ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/i486 : /G4 ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/$(cpu-type-g5) : /G5 ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/$(cpu-type-g6) : /G6 ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/$(cpu-type-g7) : /G7 ;
    -
    -        # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
    -        # tests will fail.
    -        toolset.flags $(toolset).compile CFLAGS $(conditions) : /Op ;
    -
    -        # 7.1 and below have single-threaded static RTL.
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/off/static/single : /ML ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/on/static/single : /MLd ;
    -    }
    -    else
    -    {
    -        # 8.0 and above adds some more options.
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/ : /favor:blend ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/$(cpu-type-em64t) : /favor:EM64T ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/$(cpu-type-amd64) : /favor:AMD64 ;
    -
    -        # 8.0 and above only has multi-threaded static RTL.
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/off/static/single : /MT ;
    -        toolset.flags $(toolset).compile CFLAGS $(conditions)/on/static/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
    -    local path = [ feature.get-values  :
    -        [ $(.versions).get $(version) : options ] ] ;
    +    # Use auto-detected path if possible.
    +    local path = [ feature.get-values  : [ $(.versions).get $(version)
    +        : options ] ] ;
     
         if $(path)
         {
    @@ -600,7 +895,7 @@ local rule default-path ( version )
         }
         else
         {
    -        # Check environment
    +        # Check environment.
             if $(.version-$(version)-env)
             {
                 local vc-path = [ os.environ $(.version-$(version)-env) ] ;
    @@ -614,7 +909,7 @@ local rule default-path ( version )
                 }
             }
     
    -        # Check default path
    +        # Check default path.
             if ! $(path) && $(.version-$(version)-path)
             {
                 path = [ path.native [ path.join $(.ProgramFiles) $(.version-$(version)-path) ] ] ;
    @@ -628,7 +923,7 @@ local rule default-path ( version )
     # 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 rule default-paths ( version ? )
     {
         local possible-paths ;
     
    @@ -648,417 +943,174 @@ rule default-paths ( version ? )
     }
     
     
    -# Declare generators.
    -
    -# 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 : msvc ;
    -generators.register-linker msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB : msvc ;
    -
    -generators.register-archiver msvc.archive : OBJ : STATIC_LIB : msvc ;
    -generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : msvc ;
    -generators.register-c-compiler msvc.compile.c : C : OBJ : msvc ;
    -
    -# Using 'register-c-compiler' adds the build directory to INCLUDES
    -generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : msvc ;
    -generators.override msvc.compile.rc : rc.compile.resource ;
    -generators.register-standard msvc.compile.asm : ASM : OBJ : msvc ;
    -
    -generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : msvc ;
    -generators.override msvc.compile.idl : midl.compile.idl ;
    -
    -generators.register-standard msvc.compile.mc : MC : H RC : msvc ;
    -generators.override msvc.compile.mc : mc.compile ;
    -
    -# pch support
    -
    -feature.feature pch-source : : free dependency ;
    -
    -class msvc-pch-generator : pch-generator
    +local rule get-rspline ( target : lang-opt )
     {
    -    import property-set ;
    -
    -    rule run-pch ( project name ? : property-set : sources * )
    -    {
    -        # Searching header and source file in the sources.
    -        local pch-header ;
    -        local pch-source ;
    -        for local s in $(sources)
    -        {
    -            if [ type.is-derived [ $(s).type ] H ]
    -            {
    -                pch-header = $(s) ;
    -            }
    -            else if
    -                 [ type.is-derived [ $(s).type ] CPP ]
    -              || [ type.is-derived [ $(s).type ] C ]
    -            {
    -                pch-source = $(s) ;
    -            }
    -        }
    -
    -        if ! $(pch-header)
    -        {
    -            errors.user-error "can't build pch without pch-header" ;
    -        }
    -
    -        # If we don't have PCH source - that's fine. We'll just create a
    -        # temporary .cpp file in the action.
    -
    -        local generated = [ generator.run $(project) $(name)
    -            : [ property-set.create
    -                # Passing of  is a dirty trick, needed because
    -                # non-composing generators with multiple inputs are subtly
    -                # broken. For more detailed information see:
    -                # https://zigzag.cs.msu.su:7813/boost.build/ticket/111
    -                $(pch-source)
    -                [ $(property-set).raw ] ]
    -            : $(pch-header) ] ;
    -
    -        local pch-file ;
    -        for local g in $(generated)
    -        {
    -            if [ type.is-derived [ $(g).type ] PCH ]
    -            {
    -                pch-file = $(g) ;
    -            }
    -        }
    -
    -        return [ property-set.create $(pch-header)
    -            $(pch-file) ] $(generated) ;
    -    }
    +    CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS)
    +        $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(.nl)-D$(DEFINES)
    +        $(.nl)\"-I$(INCLUDES:W)\" ] ;
     }
     
     
    -# Note: the 'H' source type will catch both '.h' header and '.hpp' header. The
    -# latter have HPP type, but HPP type is derived from H.  The type of compilation
    -# is determined entirely by the destination type.
    -generators.register [ new msvc-pch-generator msvc.compile.c.pch   : H :   C_PCH OBJ : on msvc ] ;
    -generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : on msvc ] ;
    -
    -generators.override msvc.compile.c.pch   : pch.default-c-pch-generator ;
    -generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
    -
    -flags msvc.compile PCH_FILE   on :    ;
    -flags msvc.compile PCH_SOURCE on :  ;
    -flags msvc.compile PCH_HEADER on :  ;
    -
    +# Unsafe worker rule for the register-toolset() rule. Must not be called
    +# multiple times.
     #
    -# Declare flags and action for compilation
    +local rule register-toolset-really ( )
    +{
    +    feature.extend toolset : msvc ;
    +
    +    # Intel and msvc supposedly have link-compatible objects.
    +    feature.subfeature toolset msvc : vendor : intel : propagated optional ;
    +
    +    # Inherit MIDL flags.
    +    toolset.inherit-flags msvc : midl ;
    +
    +    # Inherit MC flags.
    +    toolset.inherit-flags msvc : mc ;
    +
    +    # Dynamic runtime comes only in MT flavour.
    +    toolset.add-requirements
    +        msvc,shared:multi ;
    +
    +    # Declare msvc toolset specific features.
    +    {
    +        feature.feature debug-store : object database : propagated ;
    +        feature.feature pch-source  :                 : dependency free ;
    +    }
    +
    +    # Declare generators.
    +    {
    +        # 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 : msvc ;
    +        generators.register-linker msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB : msvc ;
    +
    +        generators.register-archiver msvc.archive : OBJ : STATIC_LIB : msvc ;
    +        generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : msvc ;
    +        generators.register-c-compiler msvc.compile.c : C : OBJ : msvc ;
    +
    +        # Using 'register-c-compiler' adds the build directory to INCLUDES.
    +        generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : msvc ;
    +        generators.override msvc.compile.rc : rc.compile.resource ;
    +        generators.register-standard msvc.compile.asm : ASM : OBJ : msvc ;
    +
    +        generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : msvc ;
    +        generators.override msvc.compile.idl : midl.compile.idl ;
    +
    +        generators.register-standard msvc.compile.mc : MC : H RC : msvc ;
    +        generators.override msvc.compile.mc : mc.compile ;
    +
    +        # Note: the 'H' source type will catch both '.h' and '.hpp' headers as
    +        # the latter have their HPP type derived from H. The type of compilation
    +        # is determined entirely by the destination type.
    +        generators.register [ new msvc-pch-generator msvc.compile.c.pch   : H :   C_PCH OBJ : on msvc ] ;
    +        generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : on msvc ] ;
    +
    +        generators.override msvc.compile.c.pch   : pch.default-c-pch-generator ;
    +        generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
    +    }
    +
    +    toolset.flags msvc.compile PCH_FILE   on :    ;
    +    toolset.flags msvc.compile PCH_SOURCE on :  ;
    +    toolset.flags msvc.compile PCH_HEADER on :  ;
    +
    +    #
    +    # Declare flags for compilation.
    +    #
    +
    +    toolset.flags msvc.compile CFLAGS speed : /O2 ;
    +    toolset.flags msvc.compile CFLAGS space : /O1 ;
    +
    +    toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/$(.cpu-type-itanium) : /G1 ;
    +    toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/$(.cpu-type-itanium2) : /G2 ;
    +
    +    toolset.flags msvc.compile CFLAGS on/object : /Z7 ;
    +    toolset.flags msvc.compile CFLAGS on/database : /Zi ;
    +    toolset.flags msvc.compile CFLAGS off : /Od ;
    +    toolset.flags msvc.compile CFLAGS off : /Ob0 ;
    +    toolset.flags msvc.compile CFLAGS on : /Ob1 ;
    +    toolset.flags msvc.compile CFLAGS full : /Ob2 ;
    +
    +    toolset.flags msvc.compile CFLAGS on : /W3 ;
    +    toolset.flags msvc.compile CFLAGS off : /W0 ;
    +    toolset.flags msvc.compile CFLAGS all : /W4 ;
    +    toolset.flags msvc.compile CFLAGS on : /WX ;
    +
    +    toolset.flags msvc.compile C++FLAGS  on/off/off : /EHs ;
    +    toolset.flags msvc.compile C++FLAGS  on/off/on : /EHsc ;
    +    toolset.flags msvc.compile C++FLAGS  on/on/off : /EHa ;
    +    toolset.flags msvc.compile C++FLAGS  on/on/on : /EHac ;
    +
    +    # By default 8.0 enables rtti support while prior versions disabled it. We
    +    # simply enable or disable it explicitly so we do not have to depend on this
    +    # default behaviour.
    +    toolset.flags msvc.compile CFLAGS on : /GR ;
    +    toolset.flags msvc.compile CFLAGS off : /GR- ;
    +    toolset.flags msvc.compile CFLAGS off/shared : /MD ;
    +    toolset.flags msvc.compile CFLAGS on/shared : /MDd ;
    +
    +    toolset.flags msvc.compile CFLAGS off/static/multi : /MT ;
    +    toolset.flags msvc.compile CFLAGS on/static/multi : /MTd ;
    +
    +    toolset.flags msvc.compile.c OPTIONS  : ;
    +    toolset.flags msvc.compile.c++ OPTIONS  : ;
    +
    +    toolset.flags msvc.compile PDB_CFLAG on/database : /Fd ;  # not used yet
    +
    +    toolset.flags msvc.compile DEFINES  ;
    +    toolset.flags msvc.compile UNDEFS  ;
    +    toolset.flags msvc.compile INCLUDES  ;
    +
    +    # Declare flags for the assembler.
    +    toolset.flags msvc.compile.asm USER_ASMFLAGS  ;
    +
    +    # Declare flags for linking.
    +    {
    +        toolset.flags msvc.link PDB_LINKFLAG on/database : /PDB: ;  # not used yet
    +        toolset.flags msvc.link LINKFLAGS on : /DEBUG ;
    +        toolset.flags msvc.link DEF_FILE  ;
    +
    +        # The linker disables the default optimizations when using /DEBUG so we
    +        # have to enable them manually for release builds with debug symbols.
    +        toolset.flags msvc LINKFLAGS on/off : /OPT:REF,ICF ;
    +
    +        toolset.flags msvc LINKFLAGS console : /subsystem:console ;
    +        toolset.flags msvc LINKFLAGS gui : /subsystem:windows ;
    +        toolset.flags msvc LINKFLAGS wince : /subsystem:windowsce ;
    +        toolset.flags msvc LINKFLAGS native : /subsystem:native ;
    +        toolset.flags msvc LINKFLAGS auto : /subsystem:posix ;
    +
    +        toolset.flags msvc.link OPTIONS  ;
    +        toolset.flags msvc.link LINKPATH  ;
    +
    +        toolset.flags msvc.link FINDLIBS_ST  ;
    +        toolset.flags msvc.link FINDLIBS_SA  ;
    +        toolset.flags msvc.link LIBRARY_OPTION msvc : "" : unchecked ;
    +        toolset.flags msvc.link LIBRARIES_MENTIONED_BY_FILE :  ;
    +    }
    +
    +    toolset.flags msvc.archive AROPTIONS  ;
    +}
    +
    +
    +# 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.
     #
    -feature.feature debug-store : object database : propagated ;
    -
    -flags msvc.compile CFLAGS speed : /O2 ;
    -flags msvc.compile CFLAGS space : /O1 ;
    -
    -flags msvc.compile CFLAGS $(.cpu-arch-ia64)/$(cpu-type-itanium) : /G1 ;
    -flags msvc.compile CFLAGS $(.cpu-arch-ia64)/$(cpu-type-itanium2) : /G2 ;
    -
    -flags msvc.compile CFLAGS on/object : /Z7 ;
    -flags msvc.compile CFLAGS on/database : /Zi ;
    -flags msvc.compile CFLAGS off : /Od ;
    -flags msvc.compile CFLAGS off : /Ob0 ;
    -flags msvc.compile CFLAGS on : /Ob1 ;
    -flags msvc.compile CFLAGS full : /Ob2 ;
    -
    -flags msvc.compile CFLAGS on : /W3 ;
    -flags msvc.compile CFLAGS off : /W0 ;
    -flags msvc.compile CFLAGS all : /W4 ;
    -flags msvc.compile CFLAGS on : /WX ;
    -
    -flags msvc.compile C++FLAGS  on/off/off : /EHs ;
    -flags msvc.compile C++FLAGS  on/off/on : /EHsc ;
    -flags msvc.compile C++FLAGS  on/on/off : /EHa ;
    -flags msvc.compile C++FLAGS  on/on/on : /EHac ;
    -
    -# By default 8.0 enables rtti support while prior versions disabled it. We
    -# simply enable or disable it expliclty so we do not have to depend on this
    -# default behaviour.
    -flags msvc.compile CFLAGS on : /GR ;
    -flags msvc.compile CFLAGS off : /GR- ;
    -flags msvc.compile CFLAGS off/shared : /MD ;
    -flags msvc.compile CFLAGS on/shared : /MDd ;
    -
    -flags msvc.compile CFLAGS off/static/multi : /MT ;
    -flags msvc.compile CFLAGS on/static/multi : /MTd ;
    -
    -flags msvc.compile.c OPTIONS  : ;
    -flags msvc.compile.c++ OPTIONS  : ;
    -
    -flags msvc.compile PDB_CFLAG on/database : /Fd ;  # not used yet
    -
    -flags msvc.compile DEFINES  ;
    -flags msvc.compile UNDEFS  ;
    -flags msvc.compile INCLUDES  ;
    -
    -
    -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:W)\" ] ;
    -}
    -
    -
    -rule compile-c-c++ ( targets + : sources * )
    -{
    -    DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
    -    DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
    -}
    -
    -
    -actions compile-c-c++
    -{
    -    $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
    -}
    -
    -
    -rule compile.c ( targets + : sources * : properties * )
    -{
    -    C++FLAGS on $(targets[1]) = ;
    -    get-rspline $(targets) : -TC ;
    -    compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
    -}
    -
    -
    -rule compile.c++ ( targets + : sources * : properties * )
    -{
    -    get-rspline $(targets) : -TP ;
    -    compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
    -}
    -
    -
    -actions compile-c-c++-pch-s
    -{
    -    $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
    -}
    -
    -
    -# Needed only to avoid messing up Emacs syntax highlighting in the messy
    -# N-quoted code below.
    -quote = "\"" ;
    -
    -actions compile-c-c++-pch
    -{
    -    $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(quote)$(>[1]:D=)$(quote))" $(.CC.FILTER)
    -}
    -
    -
    -rule compile.c.pch ( targets + : sources * : properties * )
    -{
    -    C++FLAGS on $(targets[1]) = ;
    -    get-rspline $(targets[1]) : -TC ;
    -    get-rspline $(targets[2]) : -TC ;
    -    local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
    -    if $(pch-source)
    -    {
    -        DEPENDS $(<) : $(pch-source) ;
    -        compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
    -    }
    -    else
    -    {
    -        compile-c-c++-pch $(targets) : $(sources) ;
    -    }
    -}
    -
    -
    -rule compile.c++.pch ( targets + : sources * : properties * )
    -{
    -    get-rspline $(targets[1]) : -TP ;
    -    get-rspline $(targets[2]) : -TP ;
    -    local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
    -    if $(pch-source)
    -    {
    -        DEPENDS $(<) : $(pch-source) ;
    -        compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
    -    }
    -    else
    -    {
    -        compile-c-c++-pch $(targets) : $(sources) ;
    -    }
    -}
    -
    -
    -actions compile.rc
    -{
    -    $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
    -}
    -
    -
    -# See midl.jam for details
    -TOUCH_FILE = [ common.file-touch-command ] ;
    -
    -
    -actions compile.idl
    -{
    -    $(.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)"
    -}
    -
    -
    -# Declare flags and action for the assembler
    -
    -flags msvc.compile.asm USER_ASMFLAGS  : ;
    -
    +# TODO: There used to exist a code comment for the msvc.init rule stating that
    +# we do not correctly detect the location of the vcvars32.bat setup script for
    +# the free VC7.1 tools in case user explicitly provides a path. This should be
    +# tested or simply remove this whole comment in case this toolset version is no
    +# longer important.
     #
    -# for the assembler the following options are turned on by default:
    -#
    -# -coff  generate COFF format object file (compatible with cl.exe output)
    -# -Zp4   align structures to 4 bytes
    -# -Cp    preserve case of user identifiers
    -# -Cx    preserve case in publics, externs
    -
    -actions compile.asm
    +local rule locate-default-setup ( command : parent : setup-name )
     {
    -    $(.ASM) -nologo -c -coff -Zp4 -Cp -Cx $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)"
    -}
    -
    -
    -# Declare flags and action for linking
    -flags msvc.link PDB_LINKFLAG on/database : /PDB: ;  # not used yet
    -flags msvc.link LINKFLAGS on : /DEBUG ;
    -flags msvc.link DEF_FILE  ;
    -# The linker disables the default optimizations when using /DEBUG. Whe have to
    -# enable them manually for release builds with debug symbols.
    -flags msvc LINKFLAGS on/off : /OPT:REF,ICF ;
    -
    -flags msvc LINKFLAGS console : /subsystem:console ;
    -flags msvc LINKFLAGS gui : /subsystem:windows ;
    -flags msvc LINKFLAGS wince : /subsystem:windowsce ;
    -flags msvc LINKFLAGS native : /subsystem:native ;
    -flags msvc LINKFLAGS auto : /subsystem:posix ;
    -
    -flags msvc.link OPTIONS  ;
    -flags msvc.link LINKPATH  ;
    -
    -flags msvc.link FINDLIBS_ST  ;
    -flags msvc.link FINDLIBS_SA  ;
    -flags msvc.link LIBRARY_OPTION msvc : "" : unchecked ;
    -flags msvc.link LIBRARIES_MENTIONED_BY_FILE :  ;
    -
    -flags msvc.archive AROPTIONS  ;
    -
    -
    -rule link.dll ( targets + : sources * : properties * )
    -{
    -    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.
    -if [ os.name ] in NT
    -{
    -    # The 'DEL' command would issue a message to stdout if the file does not
    -    # exist, so need a check.
    -    actions archive
    +    local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
    +    if $(result[1])
         {
    -        if exist "$(<[1])" DEL "$(<[1])"
    -        $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    +        return $(result[1]) ;
         }
     }
    -else
    -{
    -    actions archive
    -    {
    -        $(RM) "$(<[1])"
    -        $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    -    }
    -}
    -
    -
    -# Incremental linking a DLL causes no end of problems: if the actual exports
    -# 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 am sure we do not
    -# want it.
    -
    -# Windows manifest is a new way to specify dependencies on managed DotNet
    -# assemblies and Windows native DLLs. The manifests are embedded as resources
    -# and are useful in any PE target (both DLL and EXE).
    -
    -if [ os.name ] in NT
    -{
    -    actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
    -    {
    -        $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)$(LIBRARIES) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    -        if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
    -        if exist "$(<[1]).manifest" (
    -            $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
    -        )
    -    }
    -
    -    actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
    -    {
    -        $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)$(LIBRARIES) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    -        if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
    -        if exist "$(<[1]).manifest" (
    -            $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
    -        )
    -    }
    -}
    -else
    -{
    -    actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
    -    {
    -        $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)$(LIBRARIES) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    -        if test -e "$(<[1]).manifest"; then
    -            $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);1"
    -        fi
    -    }
    -
    -    actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
    -    {
    -        $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)$(LIBRARIES) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
    -        if test -e "$(<[1]).manifest"; then
    -            $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2"
    -        fi
    -    }
    -}
    -
    -
    -actions compile.mc
    -{
    -    $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
    -}
    -
    -
    -#
    -# Autodetection code
    -#     detects versions listed as '.known-versions' using registry, environment
    -#     and checking default paths. Supports both native Windows and Cygwin.
    -#
    -
    -.ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
    -
    -.known-versions = 9.0 9.0express 8.0 8.0express 7.1 7.1toolkit 7.0 6.0 ;
    -
    -# Version aliases
    -.version-alias-6 = 6.0 ;
    -.version-alias-6.5 = 6.0 ;
    -.version-alias-7 = 7.0 ;
    -.version-alias-8 = 8.0 ;
    -.version-alias-9 = 9.0 ;
    -
    -# Name of the registry key that contains Visual C++ installation path
    -#   (relative to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft"
    -.version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ;
    -.version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ;
    -.version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
    -.version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ;
    -.version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ;
    -.version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
    -.version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
    -
    -# Visual C++ Toolkit 2003 do not store its installation path in the registry.
    -# The environment variable 'VCToolkitInstallDir' and the default installation
    -# path will be checked instead.
    -.version-7.1toolkit-path    = "Microsoft Visual C++ Toolkit 2003" "bin" ;
    -.version-7.1toolkit-env     = VCToolkitInstallDir ;
    -
    -# Path to the folder containing "cl.exe" relative to the value of the
    -# corresponding environment variable.
    -.version-7.1toolkit-envpath = "bin" ;
     
     
     # Validates given path, registers found configuration and prints debug
    @@ -1074,7 +1126,7 @@ local rule register-configuration ( version : path ? )
             {
                 if $(.debug-configuration)
                 {
    -                ECHO "notice: msvc-$(version) detected, command: '$(command)'" ;
    +                ECHO "notice: [msvc-cfg] msvc-$(version) detected, command: '$(command)'" ;
                 }
     
                 $(.versions).register $(version) ;
    @@ -1083,37 +1135,96 @@ local rule register-configuration ( version : path ? )
         }
     }
     
    -if [ os.name ] in NT CYGWIN
    -{
    -    # Get installation paths from the registry.
    -    for local i in $(.known-versions)
    -    {
    -        if $(.version-$(i)-reg)
    -        {
    -            local vc-path ;
    -            for local x in "" "Wow6432Node\\"
    -            {
    -                vc-path += [ W32_GETREG
    -                "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
    -                : "ProductDir" ] ;
    -            }
     
    -            if $(vc-path)
    -            {
    -                vc-path = [ path.native [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ] ;
    -                register-configuration $(i) : $(vc-path[1]) ;
    -            }
    -        }
    -    }
    +################################################################################
    +#
    +#   Startup code executed when loading this module.
    +#
    +################################################################################
    +
    +if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
    +{
    +    .debug-configuration = true ;
     }
     
    +# Miscellaneous constants.
    +.RM = [ common.rm-command ] ;
    +.nl = "
    +" ;
    +.ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
    +.escaped-double-quote = "\"" ;
    +.TOUCH_FILE = [ common.file-touch-command ] ;
     
    -# Check environment and default installation paths.
    +# List of all registered configurations.
    +.versions = [ new configurations ] ;
     
    -for local i in $(.known-versions)
    -{
    -    if ! $(i) in [ $(.versions).all ]
    -    {
    -        register-configuration $(i) : [ default-path $(i) ] ;
    -    }
    -}
    +# Supported CPU architectures.
    +.cpu-arch-i386 =
    +    /
    +    /32
    +    x86/
    +    x86/32 ;
    +
    +.cpu-arch-amd64 =
    +    /64
    +    x86/64 ;
    +
    +.cpu-arch-ia64 =
    +    ia64/
    +    ia64/64 ;
    +
    +
    +# Supported CPU types (only Itanium optimization options are supported from
    +# VC++ 2005 on). See
    +# http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx for more
    +# detailed information.
    +.cpu-type-g5       = i586 pentium pentium-mmx ;
    +.cpu-type-g6       = i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6
    +                     k6-2 k6-3 winchip-c6 winchip2 c3 c3-2 ;
    +.cpu-type-em64t    = prescott nocona conroe conroe-xe conroe-l allendale mermon
    +                     mermon-xe kentsfield kentsfield-xe penryn wolfdale
    +                     yorksfield nehalem ;
    +.cpu-type-amd64    = k8 opteron athlon64 athlon-fx ;
    +.cpu-type-g7       = pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp
    +                     athlon-mp $(.cpu-type-em64t) $(.cpu-type-amd64) ;
    +.cpu-type-itanium  = itanium itanium1 merced ;
    +.cpu-type-itanium2 = itanium2 mckinley ;
    +
    +
    +# Known toolset versions, in order of preference.
    +.known-versions = 9.0 9.0express 8.0 8.0express 7.1 7.1toolkit 7.0 6.0 ;
    +
    +# Version aliases.
    +.version-alias-6 = 6.0 ;
    +.version-alias-6.5 = 6.0 ;
    +.version-alias-7 = 7.0 ;
    +.version-alias-8 = 8.0 ;
    +.version-alias-9 = 9.0 ;
    +
    +# Names of registry keys containing the Visual C++ installation path (relative
    +# to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
    +.version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ;
    +.version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ;
    +.version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
    +.version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ;
    +.version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ;
    +.version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
    +.version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
    +
    +# Visual C++ Toolkit 2003 does not store its installation path in the registry.
    +# The environment variable 'VCToolkitInstallDir' and the default installation
    +# path will be checked instead.
    +.version-7.1toolkit-path    = "Microsoft Visual C++ Toolkit 2003" "bin" ;
    +.version-7.1toolkit-env     = VCToolkitInstallDir ;
    +
    +# Path to the folder containing "cl.exe" relative to the value of the
    +# corresponding environment variable.
    +.version-7.1toolkit-envpath = "bin" ;
    +
    +
    +# Auto-detect all the available msvc installations on the system.
    +auto-detect-toolset-versions ;
    +
    +
    +# And finally trigger the actual Boost Build toolset registration.
    +register-toolset ;
    diff --git a/v2/tools/package.jam b/v2/tools/package.jam
    index b5cdc9fdd..25dd02565 100644
    --- a/v2/tools/package.jam
    +++ b/v2/tools/package.jam
    @@ -1,92 +1,95 @@
    -#  Copyright (c) 2005 Vladimir Prus.
    -#  Copyright 2006 Rene Rivera.
    +# Copyright (c) 2005 Vladimir Prus.
    +# Copyright 2006 Rene Rivera.
     #
    -#  Use, modification and distribution is subject to the Boost Software
    -#  License Version 1.0. (See accompanying file LICENSE_1_0.txt or
    -#  http://www.boost.org/LICENSE_1_0.txt)
    +# Use, modification and distribution is subject to the Boost Software
    +# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
    +# http://www.boost.org/LICENSE_1_0.txt)
     
    -#  Provides mechanism for installing whole packages into a specific
    -#  directory structure. This is opposed to the 'install' rule, that
    -#  installs a number of targets to a single directory, and does not
    -#  care about directory structure at all.
    +# Provides mechanism for installing whole packages into a specific directory
    +# structure. This is opposed to the 'install' rule, that installs a number of
    +# targets to a single directory, and does not care about directory structure at
    +# all.
     
    -#  Example usage:
    +# Example usage:
     #
    -#    package.install boost : 
    -#                          : 
    -#                          : 
    -#                          : 
    -#                          ;
    +#   package.install boost : 
    +#                         : 
    +#                         : 
    +#                         : 
    +#                         ;
     #
    -#  This will install binaries, libraries and headers to the 'proper' location, given
    -#  by command line options --prefix, --exec-prefix, --bindir, --libdir and 
    -#  --includedir. 
    +# This will install binaries, libraries and headers to the 'proper' location,
    +# given by command line options --prefix, --exec-prefix, --bindir, --libdir and
    +# --includedir.
     #
    -#  The rule is just a convenient wrapper, avoiding the need to define several
    -#  'install' targets.
    +# The rule is just a convenient wrapper, avoiding the need to define several
    +# 'install' targets.
     #
    -#  The only install-related feature is . It will apply to
    -#  headers only and if present, paths of headers relatively to source root will be
    -#  retained after installing. If it's not specified, then "." is assumed, so 
    -#  relative paths in headers are always preserved.
    +# The only install-related feature is . It will apply to
    +# headers only and if present, paths of headers relatively to source root will
    +# be retained after installing. If it is not specified, then "." is assumed, so
    +# relative paths in headers are always preserved.
     
    -import project ;
    -import targets ;
     import "class" : new ;
     import option ;
    -import stage ;
    +import project ;
     import property ;
    +import stage ;
    +import targets ;
    +
     
     rule install ( name : requirements * : binaries * : libraries * : headers * )
     {
    -    # If  is not specified, all headers are installed
    -    # to prefix/include, no matter what their relative path is. Sometimes
    -    # that's what needed.
    -    local install-source-root
    -        = [ property.select  : $(requirements) ] ;
    +    # If  is not specified, all headers are installed to
    +    # prefix/include, no matter what their relative path is. Sometimes that is
    +    # what is needed.
    +    local install-source-root = [ property.select  :
    +        $(requirements) ] ;
    +    install-source-root = $(install-source-root:G=) ;
         requirements = [ property.change $(requirements) :  ] ;
    -    
    -    #
    -    local install-header-subdir
    -        = [ property.select  : $(requirements) ] ;
    +
    +    local install-header-subdir = [ property.select  :
    +        $(requirements) ] ;
         install-header-subdir = /$(install-header-subdir:G=) ;
         install-header-subdir ?= "" ;
    -    requirements = [ property.change $(requirements) :  ] ;
    -    
    -    # First, figure out all locations. Use the default if no prefix option given.
    -    local prefix = [ option.get prefix :
    -        [ property.select  : $(requirements) ] ] ;
    -    requirements = [ property.change $(requirements) :  ] ;
    +    requirements = [ property.change $(requirements) :  ]
    +        ;
    +
    +    # First, figure out all locations. Use the default if no prefix option
    +    # given.
    +    local prefix = [ option.get prefix : [ property.select
    +         : $(requirements) ] ] ;
    +    prefix = $(prefix:G=) ;
    +    requirements = [ property.change $(requirements) : 
    +        ] ;
         # Or some likely defaults if neither is given.
         if ! $(prefix)
         {
             if [ modules.peek : NT ] { prefix = C:\\$(name) ; }
    -        else if [ modules.peek : UNIX ] { prefix = /usr/local ; }        
    +        else if [ modules.peek : UNIX ] { prefix = /usr/local ; }
         }
     
    -    # architecture dependent files
    +    # Architecture dependent files.
         local exec-locate = [ option.get exec-prefix : $(prefix) ] ;
    -    
    -    # binaries
    +
    +    # Binaries.
         local bin-locate = [ option.get bindir : $(prefix)/bin ] ;
     
    -    # object code libraries
    +    # Object code libraries.
         local lib-locate = [ option.get libdir : $(prefix)/lib ] ;
     
    -    # source header files
    +    # Source header files.
         local include-locate = [ option.get includedir : $(prefix)/include ] ;
     
    -    stage.install $(name)-bin : $(binaries) : $(requirements) $(bin-locate) ;
    -    stage.install $(name)-lib : 
    -        $(binaries) $(libraries) 
    -        : $(requirements) $(lib-locate) 
    -          on LIB 
    -        ;
    -    stage.install $(name)-headers : $(headers) : $(requirements) 
    -      $(include-locate)$(install-header-subdir)
    -      $(install-source-root) ;
    +    stage.install $(name)-bin : $(binaries) : $(requirements)
    +        $(bin-locate) ;
    +    stage.install $(name)-lib : $(binaries) $(libraries) : $(requirements)
    +        $(lib-locate) on LIB ;
    +    stage.install $(name)-headers : $(headers) : $(requirements)
    +        $(include-locate)$(install-header-subdir)
    +        $(install-source-root) ;
         alias $(name) : $(name)-bin $(name)-lib $(name)-headers ;
    -    
    +
         local c = [ project.current ] ;
         local project-module = [ $(c).project-module ] ;
         module $(project-module)
    diff --git a/v2/tools/python.jam b/v2/tools/python.jam
    index f8179b50f..af0011017 100644
    --- a/v2/tools/python.jam
    +++ b/v2/tools/python.jam
    @@ -650,6 +650,7 @@ local rule system-library-dependencies ( target-os )
             case windows : return ;
     
             case hpux : return  rt ;
    +        case *bsd : return  pthread gcc:util ;
     
             case aix : return  pthread dl ;
     
    @@ -867,9 +868,9 @@ local rule configure ( version ? : cmd-or-prefix ? : includes * : libraries ? :
                 framework-directory = $(framework-directory:D) ;
             }
     
    -        if $(framework-directory) = Python.framework
    +        if $(framework-directory:D=) = Python.framework
             {
    -            debug-message framework directory is \"$(fwk)\" ;
    +            debug-message framework directory is \"$(framework-directory)\" ;
             }
             else
             {
    @@ -924,7 +925,7 @@ local rule configure ( version ? : cmd-or-prefix ? : includes * : libraries ? :
               :
               : $(target-requirements)
               :
    -          : $(usage-requirements) $(fwk)
    +          : $(usage-requirements) $(framework-directory)
               ;
         }
         else
    @@ -1218,7 +1219,7 @@ rule capture-output ( target : sources * : properties * )
         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) ] ;
    +    LAUNCHER on $(target) = $(set-PYTHONPATH) [ on $(target) return \"$(PYTHON)\" ] ;
     }
     
     
    diff --git a/v2/tools/qcc.jam b/v2/tools/qcc.jam
    index bf640f529..c01256158 100644
    --- a/v2/tools/qcc.jam
    +++ b/v2/tools/qcc.jam
    @@ -6,208 +6,221 @@
     #  License Version 1.0. (See accompanying file LICENSE_1_0.txt or
     #  http://www.boost.org/LICENSE_1_0.txt)
     
    -import toolset : flags ;
    -import property ;
    -import generators ;
    -import os ;
    -import type ;
    -import feature ;
     import "class" : new ;
    -import set ;
     import common ;
     import errors ;
    +import feature ;
    +import generators ;
    +import os ;
    +import property ;
    +import set ;
    +import toolset ;
    +import type ;
    +import unix ;
     
     feature.extend toolset : qcc ;
     
    -import unix ;
     toolset.inherit-generators qcc : unix : unix.link unix.link.dll ;
     generators.override builtin.lib-generator : qcc.prebuilt ;
     toolset.inherit-flags qcc : unix ;
     toolset.inherit-rules qcc : unix ;
     
     
    -
    -# Make the "o" suffix used for qcc toolset on all
    -# platforms
    -type.set-generated-target-suffix OBJ : qcc : o ;
    +# Set typed target suffixes used by the qcc toolset.
    +type.set-generated-target-suffix OBJ        : qcc : o ;
     type.set-generated-target-suffix STATIC_LIB : qcc : a ;
     
     
    -# Initializes the qcc toolset for the given version.
    -# If necessary, command may be used to specify where the compiler
    -# is located.
    -# The parameter 'options' is a space-delimited list of options, each
    -# one being specified as option-value. Valid option names
    -# are: cxxflags, linkflags and linker-type. Accepted values for linker-type
    -# are gnu and sun, gnu being the default.
    +# Initializes the qcc toolset for the given version. If necessary, command may
    +# be used to specify where the compiler is located. The parameter 'options' is a
    +# space-delimited list of options, each one being specified as
    +# option-value. Valid option names are: cxxflags, linkflags and
    +# linker-type. Accepted values for linker-type are gnu and sun, gnu being the
    +# default.
    +#
     # Example:
     #   using qcc : 3.4 : : foo bar sun ;
    +#
     rule init ( version ? : command * : options * )
     {
         local condition = [ common.check-init-parameters qcc : version $(version) ] ;
    -    
         local command = [ common.get-invocation-command qcc : QCC : $(command) ] ;
    -
         common.handle-options qcc : $(condition) : $(command) : $(options) ;
     }
     
     
     generators.register-c-compiler qcc.compile.c++ : CPP : OBJ : qcc ;
    -generators.register-c-compiler qcc.compile.c : C : OBJ : qcc ;
    +generators.register-c-compiler qcc.compile.c   : C   : OBJ : qcc ;
     generators.register-c-compiler qcc.compile.asm : ASM : OBJ : qcc ;
     
     
    -# Declare flags for compilation
    -flags qcc.compile OPTIONS on : -gstabs+ ;
    +# Declare flags for compilation.
    +toolset.flags qcc.compile OPTIONS on : -gstabs+ ;
     
    -# Declare flags and action for compilation
    -flags qcc.compile OPTIONS off : -O0 ;
    -flags qcc.compile OPTIONS speed : -O3 ;
    -flags qcc.compile OPTIONS space : -Os ;
    +# Declare flags and action for compilation.
    +toolset.flags qcc.compile OPTIONS off : -O0 ;
    +toolset.flags qcc.compile OPTIONS speed : -O3 ;
    +toolset.flags qcc.compile OPTIONS space : -Os ;
     
    -flags qcc.compile OPTIONS off : -Wc,-fno-inline ;
    -flags qcc.compile OPTIONS on : -Wc,-Wno-inline ;
    -flags qcc.compile OPTIONS full : -Wc,-finline-functions -Wc,-Wno-inline ;
    +toolset.flags qcc.compile OPTIONS off : -Wc,-fno-inline ;
    +toolset.flags qcc.compile OPTIONS on : -Wc,-Wno-inline ;
    +toolset.flags qcc.compile OPTIONS full : -Wc,-finline-functions -Wc,-Wno-inline ;
     
    -flags qcc.compile OPTIONS off : -w ;
    -flags qcc.compile OPTIONS all : -Wc,-Wall ;
    -flags qcc.compile OPTIONS on : -Wc,-Werror ;
    +toolset.flags qcc.compile OPTIONS off : -w ;
    +toolset.flags qcc.compile OPTIONS all : -Wc,-Wall ;
    +toolset.flags qcc.compile OPTIONS on : -Wc,-Werror ;
     
    -flags qcc.compile OPTIONS on : -p ;
    +toolset.flags qcc.compile OPTIONS on : -p ;
     
    -flags qcc.compile OPTIONS  ;
    -flags qcc.compile.c++ OPTIONS  ;
    -flags qcc.compile DEFINES  ;
    -flags qcc.compile INCLUDES  ;
    +toolset.flags qcc.compile OPTIONS  ;
    +toolset.flags qcc.compile.c++ OPTIONS  ;
    +toolset.flags qcc.compile DEFINES  ;
    +toolset.flags qcc.compile INCLUDES  ;
     
    -flags qcc.compile OPTIONS shared : -shared ;
    +toolset.flags qcc.compile OPTIONS shared : -shared ;
     
    +toolset.flags qcc.compile.c++ TEMPLATE_DEPTH  ;
    +
    +
    +rule compile.c++
    +{
    +    # Here we want to raise the template-depth parameter value to something
    +    # higher than the default value of 17. Note that we could do this using the
    +    # feature.set-default rule but we do not want to set the default value for
    +    # all toolsets as well.
    +    #
    +    # TODO: This 'modified default' has been inherited from some 'older Boost
    +    # Build implementation' and has most likely been added to make some Boost
    +    # library parts compile correctly. We should see what exactly prompted this
    +    # and whether we can get around the problem more locally.
    +    local template-depth = [ on $(1) return $(TEMPLATE_DEPTH) ] ;
    +    if ! $(template-depth)
    +    {
    +        TEMPLATE_DEPTH on $(1) = 100 ;
    +    }
    +}
     
     actions compile.c++
     {
    -    "$(CONFIG_COMMAND)" -Wc,-ftemplate-depth-100 $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" 
    +    "$(CONFIG_COMMAND)" -Wc,-ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
     }
     
     actions compile.c
     {
    -    "$(CONFIG_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" 
    +    "$(CONFIG_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
     }
     
     actions compile.asm
     {
    -    "$(CONFIG_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" 
    +    "$(CONFIG_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
     }
     
    -# The class which check that we don't try to use
    -# the static property while creating or using shared library,
    -# since it's not supported by qcc/libc.
    +
    +# The class checking that we do not try to use the static property
    +# while creating or using a shared library, since it is not supported by qcc/
    +# /libc.
    +#
     class qcc-linking-generator : unix-linking-generator
     {
         rule generated-targets ( sources + : property-set : project name ? )
         {
    -        if static in [ $(property-set).raw ] 
    +        if static in [ $(property-set).raw ]
             {
                 local m ;
                 if [ id ] = "qcc.link.dll"
                 {
                     m = "on qcc, DLL can't be build with static" ;
    -            }         
    -            if ! $(m) {                
    +            }
    +            if ! $(m)
    +            {
                     for local s in $(sources)
                     {
                         local type = [ $(s).type ] ;
    -                    if $(type) &&  [ type.is-derived $(type) SHARED_LIB ] 
    +                    if $(type) && [ type.is-derived $(type) SHARED_LIB ]
                         {
                             m = "on qcc, using DLLS together with the static options is not possible " ;
    -                    }                
    -                }                
    +                    }
    +                }
                 }
                 if $(m)
                 {
    -                errors.user-error $(m) :
    -                  "it's suggested to use static together with the static" ;
    +                errors.user-error $(m) : "It is suggested to use"
    +                    "static together with static." ;
                 }
    -            
             }
    -                        
    -        return [ unix-linking-generator.generated-targets 
    +
    +        return [ unix-linking-generator.generated-targets
                 $(sources) : $(property-set) : $(project) $(name) ] ;
    -    }    
    +    }
     }
     
    -generators.register [ new qcc-linking-generator qcc.link : LIB OBJ : EXE 
    +generators.register [ new qcc-linking-generator qcc.link : LIB OBJ : EXE
         : qcc ] ;
     
    -generators.register [ new qcc-linking-generator qcc.link.dll : LIB OBJ : SHARED_LIB 
    -    : qcc ] ;
    +generators.register [ new qcc-linking-generator qcc.link.dll : LIB OBJ
    +    : SHARED_LIB : qcc ] ;
     
     generators.override qcc.prebuilt : builtin.prebuilt ;
     generators.override qcc.searched-lib-generator : searched-lib-generator ;
     
     
    +# Declare flags for linking.
    +# First, the common flags.
    +toolset.flags qcc.link OPTIONS on : -gstabs+ ;
    +toolset.flags qcc.link OPTIONS on : -p ;
    +toolset.flags qcc.link OPTIONS  ;
    +toolset.flags qcc.link LINKPATH  ;
    +toolset.flags qcc.link FINDLIBS-ST  ;
    +toolset.flags qcc.link FINDLIBS-SA  ;
    +toolset.flags qcc.link LIBRARIES  ;
     
    -# Declare flags for linking
    -# First, the common flags
    -flags qcc.link OPTIONS on : -gstabs+ ;
    -flags qcc.link OPTIONS on : -p ;
    -flags qcc.link OPTIONS  ;
    -flags qcc.link LINKPATH  ;
    -flags qcc.link FINDLIBS-ST  ;
    -flags qcc.link FINDLIBS-SA  ;
    -flags qcc.link LIBRARIES  ;
    +toolset.flags qcc.link FINDLIBS-SA : m ;
     
    -flags qcc.link FINDLIBS-SA : m ;
    -
    -# For static we made sure there are no dynamic libraries 
    -# in the link
    -flags qcc.link OPTIONS static : -static ;
    +# For static we made sure there are no dynamic libraries in the
    +# link.
    +toolset.flags qcc.link OPTIONS static : -static ;
     
     # Assuming this is just like with gcc.
    -flags qcc.link RPATH :  : unchecked ;
    -flags qcc.link RPATH_LINK :  : unchecked ;
    +toolset.flags qcc.link RPATH :  : unchecked ;
    +toolset.flags qcc.link RPATH_LINK :  : unchecked ;
     
     
    -
    -# Declare actions for linking
    +# Declare actions for linking.
    +#
     rule link ( targets * : sources * : properties * )
     {
    -    SPACE on $(targets) = " " ;    
    -    # Serialize execution of the 'link' action, since
    -    # running N links in parallel is just slower.
    -    # For now, serialize only qcc links, it might be a good
    -    # idea to serialize all links.
    +    SPACE on $(targets) = " " ;
    +    # Serialize execution of the 'link' action, since running N links in
    +    # parallel is just slower. For now, serialize only qcc links while it might
    +    # be a good idea to serialize all links.
         JAM_SEMAPHORE on $(targets) = qcc-link-semaphore ;
     }
     
     actions link bind LIBRARIES
     {
    -    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(OPTIONS) 
    +    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(OPTIONS)
     }
     
     
    -# Always remove archive and start again. Here's rationale from
    -# Andre Hentz:
    -# I had a file, say a1.c, that was included into liba.a. 
    -# I moved a1.c to a2.c, updated my Jamfiles and rebuilt. 
    -# My program was crashing with absurd errors. 
    -# After some debugging I traced it back to the fact that a1.o was *still* 
    -# in liba.a 
    +# Always remove archive and start again. Here is the rationale from Andre Hentz:
    +# I had a file, say a1.c, that was included into liba.a. I moved a1.c to a2.c,
    +# updated my Jamfiles and rebuilt. My program was crashing with absurd errors.
    +# After some debugging I traced it back to the fact that a1.o was *still* in
    +# liba.a
     RM = [ common.rm-command ] ;
    -
     if [ os.name ] = NT
     {
         RM = "if exist \"$(<[1])\" DEL \"$(<[1])\""  ;
     }
     
     
    -# Declare action for creating static libraries
    -# The 'r' letter means to add files to the archive with replacement
    -# Since we remove archive, we don't care about replacement, but
    -# there's no option "add without replacement".
    -# The 'c' letter means suppresses warning in case the archive
    -#   does not exists yet. That warning is produced only on
    -#   some platforms, for whatever reasons.
    -actions piecemeal archive 
    +# Declare action for creating static libraries. The 'r' letter means to add
    +# files to the archive with replacement. Since we remove the archive, we do not
    +# care about replacement, but there is no option to "add without replacement".
    +# The 'c' letter suppresses warnings in case the archive does not exists yet.
    +# That warning is produced only on some platforms, for whatever reasons.
    +#
    +actions piecemeal archive
     {
         $(RM) "$(<)"
         ar rc "$(<)" "$(>)"
    @@ -216,13 +229,14 @@ actions piecemeal archive
     
     rule link.dll ( targets * : sources * : properties * )
     {
    -    SPACE on $(targets) = " " ;    
    +    SPACE on $(targets) = " " ;
         JAM_SEMAPHORE on $(targets) = qcc-link-semaphore ;
     }
     
    +
     # Differ from 'link' above only by -shared.
    +#
     actions link.dll bind LIBRARIES
     {
    -    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -o "$(<)" $(HAVE_SONAME)-Wl,-h$(SPACE)-Wl,$(<[1]:D=) -shared "$(>)"  "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(OPTIONS)  
    +    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -o "$(<)" $(HAVE_SONAME)-Wl,-h$(SPACE)-Wl,$(<[1]:D=) -shared "$(>)"  "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(OPTIONS)
     }
    -
    diff --git a/v2/tools/stage.jam b/v2/tools/stage.jam
    index dee0bb446..dbfea0b84 100644
    --- a/v2/tools/stage.jam
    +++ b/v2/tools/stage.jam
    @@ -91,13 +91,15 @@ class install-target-class : basic-target
                 # for relinking.
                 local l = [ $(build-property-set).get  ] ;
                 ps-raw += $(l:G=) ;
    -        }
     
    -        # Remove the  feature on original targets.
    -        ps-raw = [ property.change $(ps-raw) :  ] ;
    -        # And . If stage target has another stage target in sources,
    -        # then we shall get virtual targets with  property set.
    -        ps-raw = [ property.change $(ps-raw) :  ] ;
    +            # Remove the  feature on original targets.
    +            ps-raw = [ property.change $(ps-raw) :  ] ;
    +
    +            # And . If stage target has another stage target in
    +            # sources, then we shall get virtual targets with the 
    +            # property set.
    +            ps-raw = [ property.change $(ps-raw) :  ] ;
    +        }
     
             local d = [ $(build-property-set).get  ] ;
             ps-raw += $(d:G=) ;
    diff --git a/v2/tools/testing.jam b/v2/tools/testing.jam
    index 05cffd39a..d9f174172 100644
    --- a/v2/tools/testing.jam
    +++ b/v2/tools/testing.jam
    @@ -3,51 +3,51 @@
     # 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 implements regression testing framework. It declares a number of
    -#  main target rules which perform some action and, if the results are ok,
    -#  creates an output file.
    +# This module implements regression testing framework. It declares a number of
    +# main target rules which perform some action and, if the results are OK,
    +# creates an output file.
     #
    -#  The exact list of rules is:
    -#  'compile'       -- creates .test file if compilation of sources was
    -#                     successful.
    -#  'compile-fail'  -- creates .test file if compilation of sources failed.
    -#  'run'           -- creates .test file is running of executable produced from
    -#                     sources was successful. Also leaves behind .output file
    -#                     with the output from program run.
    -#  'run-fail'      -- same as above, but .test file is created if running fails.
    +# The exact list of rules is:
    +# 'compile'       -- creates .test file if compilation of sources was
    +#                    successful.
    +# 'compile-fail'  -- creates .test file if compilation of sources failed.
    +# 'run'           -- creates .test file is running of executable produced from
    +#                    sources was successful. Also leaves behind .output file
    +#                    with the output from program run.
    +# 'run-fail'      -- same as above, but .test file is created if running fails.
     #
    -#  In all cases, presence of .test file is an indication that the test passed.
    -#  For more convenient reporting, you might want to use C++ Boost regression
    -#  testing utilities, see http://www.boost.org/more/regression.html
    +# In all cases, presence of .test file is an indication that the test passed.
    +# For more convenient reporting, you might want to use C++ Boost regression
    +# testing utilities (see http://www.boost.org/more/regression.html).
     #
    -#  For historical reason, a 'unit-test' rule is available which has the same
    -#  syntax as 'exe' and behaves just like 'run'.
    +# For historical reason, a 'unit-test' rule is available which has the same
    +# syntax as 'exe' and behaves just like 'run'.
     
     # Things to do:
     #  - Teach compiler_status handle Jamfile.v2.
     # Notes:
    -#  -  is not implemented, since in Como-specific, and it's not clear
    -#    how to implement it
    -#  - std::locale-support is not implemented (it's used in one test).
    +#  -  is not implemented, since it is Como-specific, and it is not
    +#    clear how to implement it
    +#  - std::locale-support is not implemented (it is used in one test).
     
     
    -import targets ;
    -import "class" : new ;
    -import property ;
    -import feature ;
    -import toolset ;
     import alias ;
    -import type ;
    -import generators ;
    -import project ;
    -import property-set ;
    -import virtual-target ;
    -import path ;
    -import os ;
    +import "class" ;
     import common ;
    -import sequence ;
     import errors ;
    +import feature ;
    +import generators ;
    +import os ;
    +import path ;
    +import project ;
    +import property ;
    +import property-set ;
     import regex ;
    +import sequence ;
    +import targets ;
    +import toolset ;
    +import type ;
    +import virtual-target ;
     
     
     rule init ( )
    @@ -81,29 +81,27 @@ type.register UNIT_TEST    : passed : TEST ;
     
     # Helper rule. Create a test target, using basename of first source if no target
     # name is explicitly passed. Remembers the created target in a global variable.
    +#
     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.
    +
    +    # 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
    +    # does not 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  forces the build system for generate paths in the
         # form '$build_dir/array1.test/gcc/debug'. This is necessary to allow
         # post-processing tools to work.
    -    local t =
    -      [ targets.create-typed-target
    -          [ type.type-from-rule-name $(target-type) ] : $(project)
    -            : $(real-name) : $(sources)
    -            : $(requirements) $(real-name).test ] ;
    -    
    +    local t = [ targets.create-typed-target [ type.type-from-rule-name
    +        $(target-type) ] : $(project) : $(real-name) : $(sources) :
    +        $(requirements) $(real-name).test ] ;
    +
         # The alias to the real target, per period replacement above.
         if $(real-name) != $(target-name)
         {
    @@ -111,9 +109,9 @@ rule make-test ( target-type : sources + : requirements * : target-name ? )
         }
     
         # 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
    -    # dump from Jamfile since projects referred by 'build-project' are not
    -    # available until the whole Jamfile is loaded.
    +    # given a project. This has some technical problems: e.g. we can not call
    +    # this dump from a Jamfile since projects referred by 'build-project' are
    +    # not available until the whole Jamfile has been loaded.
         .all-tests += $(t) ;
         return $(t) ;
     }
    @@ -121,15 +119,18 @@ rule make-test ( target-type : sources + : requirements * : target-name ? )
     
     # Note: passing more that one cpp file here is known to fail. Passing a cpp file
     # and a library target works.
    +#
     rule compile ( sources + : requirements * : target-name ? )
     {
    -    return [ make-test compile : $(sources) : $(requirements) : $(target-name) ] ;
    +    return [ make-test compile : $(sources) : $(requirements) : $(target-name) ]
    +        ;
     }
     
     
     rule compile-fail ( sources + : requirements * : target-name ? )
     {
    -    return [ make-test compile-fail : $(sources) : $(requirements) : $(target-name) ] ;
    +    return [ make-test compile-fail : $(sources) : $(requirements) :
    +        $(target-name) ] ;
     }
     
     
    @@ -141,7 +142,8 @@ rule link ( sources + : requirements * : target-name ? )
     
     rule link-fail ( sources + : requirements * : target-name ? )
     {
    -    return [ make-test link-fail : $(sources) : $(requirements) : $(target-name) ] ;
    +    return [ make-test link-fail : $(sources) : $(requirements) : $(target-name)
    +        ] ;
     }
     
     
    @@ -149,7 +151,7 @@ rule handle-input-files ( input-files * )
     {
         if $(input-files[2])
         {
    -        # Check that sorting made when creating property-set instance won't
    +        # Check that sorting made when creating property-set instance will not
             # change the ordering.
             if [ sequence.insertion-sort $(input-files) ] != $(input-files)
             {
    @@ -161,8 +163,8 @@ rule handle-input-files ( input-files * )
     }
     
     
    -rule run ( sources + : args * : input-files * : requirements * : target-name ?
    -    : default-build * )
    +rule run ( sources + : args * : input-files * : requirements * : target-name ? :
    +    default-build * )
     {
         requirements += $(args:J=" ") ;
         requirements += [ handle-input-files $(input-files) ] ;
    @@ -170,21 +172,24 @@ rule run ( sources + : args * : input-files * : requirements * : target-name ?
     }
     
     
    -rule run-fail ( sources + : args * : input-files * : requirements *
    -    : target-name ? : default-build * )
    +rule run-fail ( sources + : args * : input-files * : requirements * :
    +    target-name ? : default-build * )
     {
         requirements += $(args:J=" ") ;
         requirements += [ handle-input-files $(input-files) ] ;
    -    return [ make-test run-fail : $(sources) : $(requirements) : $(target-name) ] ;
    +    return [ make-test run-fail : $(sources) : $(requirements) : $(target-name)
    +        ] ;
     }
     
    +
     # Use 'test-suite' as a synonym for 'alias', for backward compatibility.
     IMPORT : alias : : test-suite ;
     
     
     # For all main targets in 'project-module', which are typed targets with type
     # derived from 'TEST', produce some interesting information.
    -rule dump-tests # ( project-module )
    +#
    +rule dump-tests
     {
         for local t in $(.all-tests)
         {
    @@ -195,6 +200,7 @@ rule dump-tests # ( project-module )
     
     # Given a project location in normalized form (slashes are forward), compute the
     # name of the Boost library.
    +#
     local rule get-library-name ( path )
     {
         # Path is in normalized form, so all slashes are forward.
    @@ -219,10 +225,11 @@ local rule get-library-name ( path )
     
     
     # Takes a target (instance of 'basic-target') and prints
    -# - its type
    -# - its name
    -# - comments specified via the  property
    -# - relative location of all source from the project root.
    +#   - its type
    +#   - its name
    +#   - comments specified via the  property
    +#   - relative location of all source from the project root.
    +#
     rule dump-test ( target )
     {
         local type = [ $(target).type ] ;
    @@ -230,8 +237,8 @@ rule dump-test ( target )
         local project = [ $(target).project ] ;
     
         local project-root = [ $(project).get project-root ] ;
    -    local library = [ get-library-name
    -        [ path.root [ $(project).get location ] [ path.pwd ] ] ] ;
    +    local library = [ get-library-name [ path.root [ $(project).get location ]
    +        [ path.pwd ] ] ] ;
         if $(library)
         {
             name = $(library)/$(name) ;
    @@ -243,19 +250,16 @@ rule dump-test ( target )
         {
             if [ class.is-a $(s) : file-reference ]
             {
    -            local location =
    -              [ path.root
    -                  [ path.root [ $(s).name ] [ $(s).location ] ]
    -                  [ path.pwd ] ] ;
    +            local location = [ path.root [ path.root [ $(s).name ]
    +                [ $(s).location ] ] [ path.pwd ] ] ;
     
    -            source-files +=
    -              [ path.relative
    -                  $(location)
    -                  [ path.root $(project-root) [ path.pwd ] ] ] ;
    +            source-files += [ path.relative-to [ path.root $(project-root)
    +                [ path.pwd ] ] $(location) ] ;
             }
         }
     
    -    local target-name = [ $(project).get location ] // [ $(target).name ] .test ;
    +    local target-name = [ $(project).get location ] // [ $(target).name ] .test
    +        ;
         target-name = $(target-name:J=) ;
     
         local r = [ $(target).requirements ] ;
    @@ -281,9 +285,8 @@ rule dump-test ( target )
             # Format them into a single string of quoted strings.
             test-info = \"$(test-info:J=\"\ \")\" ;
     
    -        ECHO boost-test($(type)) \"$(name)\"
    -            [$(test-info)]
    -            ":" \"$(source-files)\" ;
    +        ECHO boost-test($(type)) \"$(name)\" [$(test-info)] ":"
    +            \"$(source-files)\" ;
         }
     }
     
    @@ -300,10 +303,10 @@ generators.register-standard testing.expect-success : EXE        : LINK
     # Generator which runs an EXE and captures output.
     generators.register-standard testing.capture-output : EXE : RUN_OUTPUT ;
     
    -# Generator which creates a target if sources runs successfully. Differs from
    -# RUN in that run output is not captured. The reason why it exists is that the
    -# 'run' rule is much better for automated testing, but is not user-friendly. See
    -# http://article.gmane.org/gmane.comp.lib.boost.build/6353/
    +# Generator which creates a target if sources run successfully. Differs from RUN
    +# in that run output is not captured. The reason why it exists is that the 'run'
    +# rule is much better for automated testing, but is not user-friendly (see
    +# http://article.gmane.org/gmane.comp.lib.boost.build/6353).
     generators.register-standard testing.unit-test : EXE : UNIT_TEST ;
     
     
    @@ -311,13 +314,16 @@ generators.register-standard testing.unit-test : EXE : UNIT_TEST ;
     
     # Causes the 'target' to exist after bjam invocation if and only if all the
     # dependencies were successfully built.
    +#
     rule expect-success ( target : dependency + : requirements * )
     {
         **passed** $(target) : $(sources) ;
     }
     
    +
     # Causes the 'target' to exist after bjam invocation if and only if all some of
     # the dependencies were not successfully built.
    +#
     rule expect-failure ( target : dependency + : properties * )
     {
         local grist = [ MATCH ^<(.*)> : $(dependency:G) ] ;
    @@ -332,13 +338,14 @@ rule expect-failure ( target : dependency + : properties * )
     }
     
     
    -# The rule/action combination used to report successfull passing of a test.
    +# The rule/action combination used to report successful passing of a test.
    +#
     rule **passed**
     {
         # Dump all the tests, if needed. We do it here, since dump should happen
    -    # only after all Jamfiles have been read, and there's no such place
    +    # only after all Jamfiles have been read, and there is no such place
         # currently defined (but there should be).
    -    if ! $(.dumped-tests) && --dump-tests in [ modules.peek : ARGV ]
    +    if ! $(.dumped-tests) && ( --dump-tests in [ modules.peek : ARGV ] )
         {
             .dumped-tests = true ;
             dump-tests ;
    @@ -349,15 +356,20 @@ rule **passed**
     }
     
     
    +# Used to create test files signifying passed tests.
    +#
     actions **passed**
     {
    -    echo passed > $(<)
    +    echo passed > "$(<)"
     }
     
     
    +# Used to create replacement object files that do not get created during tests
    +# that are expected to fail.
    +#
     actions (failed-as-expected)
     {
    -    echo failed as expected > $(<)
    +    echo failed as expected > "$(<)"
     }
     
     
    @@ -398,6 +410,7 @@ toolset.flags testing.capture-output LAUNCHER  ;
     #   - if 'none', does not remove anything, ever
     #   - if empty, removes 'source'
     #   - if non-empty and not 'none', contains a list of sources to remove.
    +#
     rule capture-output ( target : source : properties * : targets-to-remove * )
     {
         output-file on $(target) = $(target:S=.output) ;
    @@ -405,7 +418,7 @@ rule capture-output ( target : source : properties * : targets-to-remove * )
     
         # The INCLUDES kill a warning about independent target...
         INCLUDES $(target) : $(target:S=.output) ;
    -    # but it also puts .output into dependency graph, so we must tell jam it's
    +    # but it also puts .output into dependency graph, so we must tell jam it is
         # OK if it cannot find the target or updating rule.
         NOCARE $(target:S=.output) ;
     
    @@ -431,12 +444,12 @@ rule capture-output ( target : source : properties * : targets-to-remove * )
         {
             TEMPORARY $(targets-to-remove) ;
             # Set a second action on target that will be executed after capture
    -        # output action. The 'RmTemps' rule has the 'ignore' modifier so it's
    +        # output action. The 'RmTemps' rule has the 'ignore' modifier so it is
             # always considered succeeded. This is needed for 'run-fail' test. For
             # that test the target will be marked with FAIL_EXPECTED, and without
             # 'ignore' successful execution will be negated and be reported as
    -        # failure. With 'ignore' we don't detect a case where removing files
    -        # fails, but it's not likely to happen.
    +        # failure. With 'ignore' we do not detect a case where removing files
    +        # fails, but it is not likely to happen.
             RmTemps $(target) : $(targets-to-remove) ;
         }
     }
    @@ -444,77 +457,77 @@ rule capture-output ( target : source : properties * : targets-to-remove * )
     
     if [ os.name ] = NT
     {
    -    STATUS        = %status% ;
    -    SET_STATUS    = "set status=%ERRORLEVEL%" ;
    -    RUN_OUTPUT_NL = "echo." ;
    -    STATUS_0      = "%status% EQU 0 (" ;
    -    STATUS_NOT_0  = "%status% NEQ 0 (" ;
    -    VERBOSE       = "%verbose% EQU 1 (" ;
    -    ENDIF         = ")" ;
    -    SHELL_SET     = "set " ;
    -    CATENATE      = type ;
    -    CP            = copy ;
    +    .STATUS        = %status% ;
    +    .SET_STATUS    = "set status=%ERRORLEVEL%" ;
    +    .RUN_OUTPUT_NL = "echo." ;
    +    .STATUS_0      = "%status% EQU 0 (" ;
    +    .STATUS_NOT_0  = "%status% NEQ 0 (" ;
    +    .VERBOSE       = "%verbose% EQU 1 (" ;
    +    .ENDIF         = ")" ;
    +    .SHELL_SET     = "set " ;
    +    .CATENATE      = type ;
    +    .CP            = copy ;
     }
     else
     {
    -    STATUS        = "$status" ;
    -    SET_STATUS    = "status=$?" ;
    -    RUN_OUTPUT_NL = "echo" ;
    -    STATUS_0      = "test $status -eq 0 ; then" ;
    -    STATUS_NOT_0  = "test $status -ne 0 ; then" ;
    -    VERBOSE       = "test $verbose -eq 1 ; then" ;
    -    ENDIF         = "fi" ;
    -    SHELL_SET     = "" ;
    -    CATENATE      = cat ;
    -    CP            = cp ;
    +    .STATUS        = "$status" ;
    +    .SET_STATUS    = "status=$?" ;
    +    .RUN_OUTPUT_NL = "echo" ;
    +    .STATUS_0      = "test $status -eq 0 ; then" ;
    +    .STATUS_NOT_0  = "test $status -ne 0 ; then" ;
    +    .VERBOSE       = "test $verbose -eq 1 ; then" ;
    +    .ENDIF         = "fi" ;
    +    .SHELL_SET     = "" ;
    +    .CATENATE      = cat ;
    +    .CP            = cp ;
     }
     
    +
    +.VERBOSE_TEST = 0 ;
     if --verbose-test in [ modules.peek : ARGV ]
     {
    -    VERBOSE_TEST = 1 ;
    -}
    -else
    -{
    -    VERBOSE_TEST = 0 ;
    +    .VERBOSE_TEST = 1 ;
     }
     
     
    -RM = [ common.rm-command ] ;
    +.RM = [ common.rm-command ] ;
     
     
     actions capture-output bind INPUT_FILES output-file
     {
         $(PATH_SETUP)
         $(LAUNCHER) "$(>)" $(ARGS) "$(INPUT_FILES)" > "$(output-file)" 2>&1
    -    $(SET_STATUS)
    -    $(RUN_OUTPUT_NL) >> "$(output-file)"
    -    echo EXIT STATUS: $(STATUS) >> "$(output-file)"
    -    if $(STATUS_0)
    -        $(CP) "$(output-file)" "$(<)"
    -    $(ENDIF)
    -    $(SHELL_SET)verbose=$(VERBOSE_TEST)
    -    if $(STATUS_NOT_0)
    -        $(SHELL_SET)verbose=1
    -    $(ENDIF)
    -    if $(VERBOSE)
    +    $(.SET_STATUS)
    +    $(.RUN_OUTPUT_NL) >> "$(output-file)"
    +    echo EXIT STATUS: $(.STATUS) >> "$(output-file)"
    +    if $(.STATUS_0)
    +        $(.CP) "$(output-file)" "$(<)"
    +    $(.ENDIF)
    +    $(.SHELL_SET)verbose=$(.VERBOSE_TEST)
    +    if $(.STATUS_NOT_0)
    +        $(.SHELL_SET)verbose=1
    +    $(.ENDIF)
    +    if $(.VERBOSE)
             echo ====== BEGIN OUTPUT ======
    -        $(CATENATE) "$(output-file)"
    +        $(.CATENATE) "$(output-file)"
             echo ====== END OUTPUT ======
    -    $(ENDIF)
    -    exit $(STATUS)
    +    $(.ENDIF)
    +    exit $(.STATUS)
     }
     
     
     actions quietly updated ignore piecemeal together RmTemps
     {
    -    $(RM) "$(>)"
    +    $(.RM) "$(>)"
     }
     
     
    -MAKE_FILE = [ common.file-creation-command ] ;
    +.MAKE_FILE = [ common.file-creation-command ] ;
     
     toolset.flags testing.unit-test LAUNCHER  ;
     toolset.flags testing.unit-test ARGS  ;
    +
    +
     rule unit-test ( target : source : properties * )
     {
         run-path-setup $(target) : $(source) : $(properties) ;
    @@ -524,9 +537,10 @@ rule unit-test ( target : source : properties * )
     actions unit-test
     {
         $(PATH_SETUP)
    -    $(LAUNCHER) $(>) $(ARGS) && $(MAKE_FILE) $(<)
    +    $(LAUNCHER) $(>) $(ARGS) && $(.MAKE_FILE) $(<)
     }
     
    +
     IMPORT $(__name__) : compile compile-fail run run-fail link link-fail
         : : compile compile-fail run run-fail link link-fail ;
     
    @@ -542,9 +556,14 @@ rule record-time ( target : source : start end user system )
         SYSTEM_TIME on $(target) += $(src-string)$(system) ;
     }
     
    +
     IMPORT testing : record-time : : testing.record-time ;
     
     
    +# Calling this rule requests that Boost Build time how long it taks to build the
    +# 'source' target and display the results both on the standard output and in the
    +# 'target' file.
    +#
     rule time ( target : source : properties *  )
     {
         # Set up rule for recording timing information.
    @@ -561,6 +580,6 @@ actions time
         echo user: $(USER_TIME)
         echo system: $(SYSTEM_TIME)
     
    -    echo user: $(USER_TIME)" seconds" > $(<)
    -    echo system: $(SYSTEM_TIME)" seconds" > $(<)
    +    echo user: $(USER_TIME)" seconds" > "$(<)"
    +    echo system: $(SYSTEM_TIME)" seconds" >> "$(<)"
     }
    diff --git a/v2/tools/types/exe.jam b/v2/tools/types/exe.jam
    index 178355eb2..af6b33e46 100644
    --- a/v2/tools/types/exe.jam
    +++ b/v2/tools/types/exe.jam
    @@ -1,5 +1,9 @@
     # Copyright David Abrahams 2004. 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)
    -type EXE : exe : : NT CYGWIN ;
    -type EXE ;
    +
    +import type ;
    +
    +type.register EXE ;
    +type.set-generated-target-suffix EXE : windows : "exe" ;
    +type.set-generated-target-suffix EXE : cygiwn : "exe" ;
    diff --git a/v2/tools/types/lib.jam b/v2/tools/types/lib.jam
    index 6421aab07..45446cbe1 100644
    --- a/v2/tools/types/lib.jam
    +++ b/v2/tools/types/lib.jam
    @@ -7,23 +7,25 @@ import os ;
     
     type.register LIB ;
     
    -if [ os.on-unix ]
    -{
    -    type.set-generated-target-prefix LIB : : "lib" ;
    -}
    +type.set-generated-target-prefix LIB : : "lib" ;
    +type.set-generated-target-prefix LIB : windows : "" ;
    +type.set-generated-target-prefix LIB : cygwin : "" ;
     
    -type STATIC_LIB : lib a : LIB : NT CYGWIN ;
    -type STATIC_LIB : a : LIB : MACOSX ;
    -type STATIC_LIB : a : LIB ;
    +# FIXME: should not register both extensions on both
    +# platforms.
    +type.register STATIC_LIB : a lib : LIB ;
    +
    +type.set-generated-target-suffix STATIC_LIB : windows : lib ;
    +type.set-generated-target-suffix STATIC_LIB : cygwin : lib ;
     type.set-generated-target-prefix STATIC_LIB : : lib ;
     
     type IMPORT_LIB : : STATIC_LIB ;
     type.set-generated-target-suffix IMPORT_LIB : : lib ;
     type.set-generated-target-prefix IMPORT_LIB : : "" ;
     
    -type SHARED_LIB : dll : LIB : NT CYGWIN ;
    -type SHARED_LIB : dylib : LIB : MACOSX ;
    -type SHARED_LIB : so : LIB ;
    +type.register SHARED_LIB : so dll dylib : LIB ;
    +type.set-generated-target-suffix SHARED_LIB : windows : dll ;
    +type.set-generated-target-suffix SHARED_LIB : darwin : dylib ;
     
     type SEARCHED_LIB : : LIB ;
     # This is needed so that when we create a target of SEARCHED_LIB
    diff --git a/v2/tools/types/obj.jam b/v2/tools/types/obj.jam
    index d505b71f7..6afbcaa6f 100644
    --- a/v2/tools/types/obj.jam
    +++ b/v2/tools/types/obj.jam
    @@ -1,5 +1,9 @@
     # Copyright David Abrahams 2004. 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)
    -type OBJ : obj : : NT CYGWIN ;
    -type OBJ : o ;
    +
    +import type ;
    +
    +type.register OBJ : o obj ;
    +type.set-generated-target-suffix OBJ : windows : obj ;
    +type.set-generated-target-suffix OBJ : cygwin : obj ;
    diff --git a/v2/tools/vacpp.jam b/v2/tools/vacpp.jam
    index c415fc299..5addf28e3 100644
    --- a/v2/tools/vacpp.jam
    +++ b/v2/tools/vacpp.jam
    @@ -60,7 +60,7 @@ flags vacpp C++FLAGS on : -qrtti ;
     # Enable 64-bit memory addressing model
     flags vacpp CFLAGS 64 : -q64 ;
     flags vacpp LINKFLAGS 64 : -q64 ;
    -flags vacpp ARFLAGS 64 : -X 64 ;
    +flags vacpp ARFLAGS aix/64 : -X 64 ;
     
     # Use absolute path when generating debug information
     flags vacpp CFLAGS on : -g -qfullpath ;
    diff --git a/v2/util/doc.jam b/v2/util/doc.jam
    index 5ebf6e2bc..a75155882 100644
    --- a/v2/util/doc.jam
    +++ b/v2/util/doc.jam
    @@ -606,7 +606,7 @@ local rule print-help-project (
         : jamfile *  # The project Jamfile.
     )
     {
    -    if $(jamfile<$(jamfile)>.docs[1])
    +    if $(jamfile<$(jamfile)>.docs)
         {
             # Print the docs.
             print.section "Project-specific help"
    @@ -625,7 +625,7 @@ local rule print-help-config (
         config-file  # The configuration Jamfile.
     )
     {
    -    if $(jamfile<$(config-file)>.docs[1])
    +    if $(jamfile<$(config-file)>.docs)
         {
             # Print the docs.
             print.section "Configuration help"
    @@ -649,7 +649,7 @@ local rule extract-comment (
         local l = [ MATCH "^[$(ws)]*(#)(.*)$" : $(line) ] ;
         while $(l[1]) && $($(var))
         {
    -        if $(l[2]) { comment += [ MATCH "^[$(ws)](.*)$" : $(l[2]) ] ; }
    +        if $(l[2]) { comment += [ MATCH "^[$(ws)]?(.*)$" : $(l[2]) ] ; }
             else { comment += "" ; }
             $(var) = $($(var)[2-]) ;
             line = $($(var)[1]) ;
    @@ -908,7 +908,7 @@ rule scan-module (
                 set-module-copyright $(module-name) : $(comment-block) ;
             }
             else if $(action[1]) in "print-help-project" "print-help-config"
    -            && ! $(jamfile<$(target)>.docs[1])
    +            && ! $(jamfile<$(target)>.docs)
             {
                 # special module docs for the project jamfile.
                 jamfile<$(target)>.docs = $(comment-block) ;
    diff --git a/v2/util/numbers.jam b/v2/util/numbers.jam
    index ec546689e..665347d31 100644
    --- a/v2/util/numbers.jam
    +++ b/v2/util/numbers.jam
    @@ -6,35 +6,9 @@
     import errors ;
     
     
    -digits = 0 1 2 3 4 5 6 7 8 9 ;
    -powers = 1 ;
    -zeros = "" ;
    -natural = $(digits) ;
    -positive = $(digits[2-]) ;
    -incr = $(positive[2-]) ;
    -znatural = $(digits) ;
    -zero-test = is zero ;  # if $(zero-test[$(n)]) == "is" "zero", n == 0
    -
    -
    -local rule extend ( )
    -{
    -    local next = $(digits[2-])$(znatural) ;
    -    natural += $(next) ;
    -    positive += $(next) ;
    -    incr += $(next) ;
    -    znatural = $(digits)$(znatural) ;
    -}
    -
    -
     rule trim-leading-zeroes ( value )
     {
    -    local value2 = [ MATCH "^0(.*)$" : $(value) ] ;
    -    while $(value2)
    -    {
    -        value = $(value2) ;
    -        value2 = [ MATCH "^0(.*)$" : $(value) ] ;
    -    }
    -    return $(value:E="") ;
    +    return [ CALC $(value) + 0 ] ;
     }
     
     
    @@ -76,45 +50,22 @@ rule range ( start finish ? : step ? )
     
         if $(finish) != 0
         {
    -        while ! $(positive[$(finish)])
    +        local result ;
    +        while [ less $(start) $(finish) ] || $(start) = $(finish)
             {
    -            extend ;
    -        }
    -
    -        if $(step) = 1
    -        {
    -            return $(positive[$(start)-$(finish)]) ;
    -        }
    -        else
    -        {
    -            local index = [ increment $(step) ] ;
    -            local by1 = $(positive[$(start)-$(finish)]) ;
    -            local result ;
    -            while $(by1)
    -            {
    -                result += $(by1[1]) ;
    -                by1 = $(by1[$(index)-]) ;
    -            }
    -            return $(result) ;
    +            result += $(start) ;
    +            start = [ CALC $(start) + $(step) ] ;
             }
    +        return $(result) ;
         }
     }
     
     
     rule less ( n1 n2 )
     {
    -    check $(n1) $(n2) ;
    -    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?
    -    if ( $(l1) < $(l2) ) || ( ( $(l1) = $(l2) ) && $(n1) < $(n2) )
    +    switch [ CALC $(n2) - $(n1) ]
         {
    -        return true ;
    +        case [1-9]* : return true ;
         }
     }
     
    @@ -184,10 +135,10 @@ rule __test__ ( )
         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 1000123456  : trim-leading-zeroes 1000123456  ;
         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 ;
    diff --git a/v2/util/option.jam b/v2/util/option.jam
    index 4c4128359..c222e3107 100644
    --- a/v2/util/option.jam
    +++ b/v2/util/option.jam
    @@ -6,6 +6,7 @@
     
     import modules ;
     
    +
     rule get ( name : default-value ? )
     {
         local m = [ MATCH --$(name)=(.*) : [ modules.peek : ARGV ] ] ;
    @@ -16,23 +17,22 @@ rule get ( name : default-value ? )
         else
         {
             return $(default-value) ;
    -    }        
    +    }
     }
     
     
    +# Check command-line args as soon as possible. For each option try to load
    +# module named after option. Is that succeeds, invoke 'process' rule in the
    +# module. The rule may return "true" to indicate that the regular build process
    +# should not be attempted.
    +#
    +# Options take the general form of: --[=] []
    +#
     rule process ( )
    -{ 
    -    # Check command-line args as soon as possible.  For each option try
    -    # to load module named after option. Is that succeeds, invoke 'process'
    -    # rule in the module. The rule may return "true" to indicate that the
    -    # regular build process should not be attempted.
    -    #
    -    # Options take the general form of: --[=] []
    -    #
    -    
    +{
         local ARGV = [ modules.peek : ARGV ] ;
         local BOOST_BUILD_PATH = [ modules.peek : BOOST_BUILD_PATH ] ;
    -    
    +
         local dont-build ;
         local args = $(ARGV) ;
         while $(args)
    @@ -62,27 +62,26 @@ rule process ( )
                     args = $(args[2-]) ;
                 }
     
    -            # look in options subdirectories of BOOST_BUILD_PATH for modules
    +            # Jook in options subdirectories of BOOST_BUILD_PATH for modules
                 # matching the full option name and then its prefix.
                 local plugin-dir = options ;
    -            local option-files = [
    -              GLOB $(plugin-dir:D=$(BOOST_BUILD_PATH)) : $(full-name).jam $(prefix).jam
    -            ] ;
    +            local option-files = [ GLOB $(plugin-dir:D=$(BOOST_BUILD_PATH)) :
    +                $(full-name).jam $(prefix).jam ] ;
     
                 if $(option-files)
                 {
    -                # load the file into a module named for the option
    +                # Load the file into a module named for the option.
                     local f = $(option-files[1]) ;
                     local module-name = --$(f:D=:S=) ;
                     modules.load $(module-name) : $(f:D=) : $(f:D) ;
     
    -                # if there's a process rule, call it with the full option name
    -                # and its value (if any).  If there was no "=" in the option,
    -                # the value will be empty.
    +                # If there is a process rule, call it with the full option name
    +                # and its value (if any). If there was no "=" in the option, the
    +                # value will be empty.
                     if process in [ RULENAMES $(module-name) ]
                     {
    -                    dont-build +=
    -                      [ modules.call-in $(module-name) : process --$(full-name) : $(values) ] ;
    +                    dont-build += [ modules.call-in $(module-name) : process
    +                        --$(full-name) : $(values) ] ;
                     }
                 }
             }
    @@ -90,4 +89,3 @@ rule process ( )
     
         return $(dont-build) ;
     }
    -
    diff --git a/v2/util/path.jam b/v2/util/path.jam
    index 3dfb6ff41..bf00b8e1b 100644
    --- a/v2/util/path.jam
    +++ b/v2/util/path.jam
    @@ -213,15 +213,11 @@ rule root ( path root )
     #
     rule pwd ( )
     {
    -    if $(.pwd)
    -    {
    -        return $(.pwd) ;
    -    }
    -    else
    +    if ! $(.pwd)
         {
             .pwd = [ make [ PWD ] ] ;
    -        return $(.pwd) ;
         }
    +    return $(.pwd) ;
     }
     
     
    @@ -264,8 +260,8 @@ rule glob ( dirs * : patterns + : exclude-patterns * )
         local exc = [ GLOB-RECURSIVELY $(real-exclude-patterns) ] ;
         exc = [ sequence.transform NORMALIZE_PATH : $(exc) ] ;
     
    -    return [ sequence.transform path.make :
    -        [ set.difference $(inc) : $(exc) ] ] ;
    +    return [ sequence.transform path.make : [ set.difference $(inc) : $(exc) ] ]
    +        ;
     }
     
     
    @@ -277,11 +273,8 @@ rule glob ( dirs * : patterns + : exclude-patterns * )
     #
     rule glob-tree ( roots * : patterns + : exclude-patterns * )
     {
    -    return [ sequence.transform path.make : [ .glob-tree
    -        [ sequence.transform path.native : $(roots) ]
    -        : $(patterns)
    -        : $(exclude-patterns)
    -        ] ] ;
    +    return [ sequence.transform path.make : [ .glob-tree [ sequence.transform
    +        path.native : $(roots) ] : $(patterns) : $(exclude-patterns) ] ] ;
     }
     
     
    @@ -292,17 +285,20 @@ local rule .glob-tree ( roots * : patterns * : exclude-patterns * )
         {
             excluded = [ GLOB $(roots) : $(exclude-patterns) ] ;
         }
    -    local result = [ set.difference
    -        [ GLOB $(roots) : $(patterns) ] : $(excluded) ] ;
    +    local result = [ set.difference [ GLOB $(roots) : $(patterns) ] :
    +        $(excluded) ] ;
         local subdirs ;
    -    for local d in [ set.difference
    -        [ GLOB $(roots) : * ] : $(excluded) ]
    +    for local d in [ set.difference [ GLOB $(roots) : * ] : $(excluded) ]
         {
    -        if ! ( $(d:D=) in . .. ) && ! [ CHECK_IF_FILE $(d) ] { subdirs += $(d) ; }
    +        if ! ( $(d:D=) in . .. ) && ! [ CHECK_IF_FILE $(d) ]
    +        {
    +            subdirs += $(d) ;
    +        }
         }
         if $(subdirs)
         {
    -        result += [ .glob-tree $(subdirs) : $(patterns) : $(exclude-patterns) ] ;
    +        result += [ .glob-tree $(subdirs) : $(patterns) : $(exclude-patterns) ]
    +            ;
         }
         return $(result) ;
     }
    @@ -326,32 +322,33 @@ rule all-parents ( path : upper_limit ? : cwd ? )
         cwd ?= [ pwd ] ;
         local path_ele = [ regex.split [ root $(path) $(cwd) ] "/" ] ;
     
    -    if ! $(upper_limit) {
    +    if ! $(upper_limit)
    +    {
             upper_limit = / ;
         }
         local upper_ele = [ regex.split [ root $(upper_limit) $(cwd) ] "/" ] ;
     
    -    # Leave only elements in 'path_ele' below 'upper_ele'
    -    while $(path_ele) && $(upper_ele[1]) = $(path_ele[1]) {
    +    # Leave only elements in 'path_ele' below 'upper_ele'.
    +    while $(path_ele) && ( $(upper_ele[1]) = $(path_ele[1]) )
    +    {
             upper_ele = $(upper_ele[2-]) ;
             path_ele = $(path_ele[2-]) ;
         }
     
    -    # All upper elements removed ?
    -    if ! $(upper_ele)
    -    {
    -        # Create the relative paths to parents, number of elements in 'path_ele'
    -        local result ;
    -        for local i in $(path_ele) {
    -            path = [ parent $(path) ] ;
    -            result += $(path) ;
    -        }
    -        return $(result) ;
    -    }
    -    else
    +    # Have all upper elements been removed ?
    +    if $(upper_ele)
         {
             errors.error "$(upper_limit) is not prefix of $(path)" ;
         }
    +    
    +    # Create the relative paths to parents, number of elements in 'path_ele'.
    +    local result ;
    +    for local i in $(path_ele)
    +    {
    +        path = [ parent $(path) ] ;
    +        result += $(path) ;
    +    }
    +    return $(result) ;
     }
     
     
    diff --git a/v2/util/regex.jam b/v2/util/regex.jam
    index 1b59f86a8..234c36f62 100644
    --- a/v2/util/regex.jam
    +++ b/v2/util/regex.jam
    @@ -1,17 +1,18 @@
    -# Copyright 2001, 2002 Dave Abrahams 
    -# Copyright 2003 Douglas Gregor 
    -# Copyright 2003 Rene Rivera 
    -# Copyright 2002, 2003, 2004, 2005 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 2003 Douglas Gregor
    +# Copyright 2003 Rene Rivera
    +# Copyright 2002, 2003, 2004, 2005 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 a list of the following substrings:
    -#   1) from beginning till the first occurence of 'separator' or till the end,
    -#   2) between each occurence of 'separator' and the next occurence,
    -#   3) from the last occurence of 'separator' till the end.
    +#   1) from beginning till the first occurrence of 'separator' or till the end,
    +#   2) between each occurrence of 'separator' and the next occurrence,
    +#   3) from the last occurrence of 'separator' till the end.
     #   If no separator is present, the result will contain only one element.
     #
    +
     rule split ( string separator )
     {
         local result ;
    @@ -22,20 +23,23 @@ rule split ( string separator )
         while $(match)
         {
             match = [ MATCH ^(.*)($(separator))(.*) : $(s) ] ;
    -        if $(match) {
    -            match += "" ; # in case 3rd item was empty - works around MATCH bug
    +        if $(match)
    +        {
    +            match += "" ;  # in case 3rd item was empty - works around MATCH bug
                 result = $(match[3]) $(result) ;
                 s = $(match[1]) ;
             }
         }
         # Combine the remaining part at the beginning, which does not have
    -    # separators, with the pieces broken off.
    -    # Note that rule's signature does not allow initial s to be empty.
    +    # separators, with the pieces broken off. Note that the rule's signature
    +    # does not allow the initial s to be empty.
         return $(s) $(result) ;
     }
     
    -# Returns the concatenated results of Applying regex.split to every
    -# element of list using the separator pattern.
    +
    +# Returns the concatenated results of Applying regex.split to every element of
    +# the list using the separator pattern.
    +#
     rule split-list ( list * : separator )
     {
         local result ;
    @@ -45,9 +49,10 @@ rule split-list ( list * : separator )
         }
         return $(result) ;
     }
    -  
    -# Match string against pattern, and return the elements indicated by
    -# indices.
    +
    +
    +# Match string against pattern, and return the elements indicated by indices.
    +#
     rule match ( pattern : string : indices * )
     {
         indices ?= 1 2 3 4 5 6 7 8 9 ;
    @@ -55,10 +60,10 @@ rule match ( pattern : string : indices * )
         return $(x[$(indices)]) ;
     }
     
    -# Matches all elements of 'list' agains the 'pattern' 
    -# and returns a list of the elements indicated by indices of 
    -# all successfull matches. If 'indices' is omitted returns
    -# a list of first paranthethised groups of all successfull
    +
    +# Matches all elements of 'list' agains the 'pattern' and returns a list of
    +# elements indicated by indices of all successful matches. If 'indices' is
    +# omitted returns a list of first paranthethised groups of all successful
     # matches.
     #
     rule transform ( list * : pattern : indices * )
    @@ -71,41 +76,44 @@ rule transform ( list * : pattern : indices * )
             if $(m)
             {
                 result += $(m[$(indices)]) ;
    -        }        
    +        }
         }
         return $(result) ;
     }
     
     NATIVE_RULE regex : transform ;
     
    -# Escapes all of the characters in symbols using the escape symbol
    -# escape-symbol for the given string, and returns the escaped string
    +
    +# Escapes all of the characters in symbols using the escape symbol escape-symbol
    +# for the given string, and returns the escaped string.
    +#
     rule escape ( string : symbols : escape-symbol )
     {
    -  local result = "" ;
    -  local m = 1 ;
    -  while $(m)
    -  {
    -    m = [ MATCH ^([^$(symbols)]*)([$(symbols)])(.*) : $(string) ] ;
    -    if $(m)
    +    local result = "" ;
    +    local m = 1 ;
    +    while $(m)
         {
    -      m += "" ;  # Supposedly a bug fix; borrowed from regex.split
    -      result = "$(result)$(m[1])$(escape-symbol)$(m[2])" ;
    -      string = $(m[3]) ;
    +        m = [ MATCH ^([^$(symbols)]*)([$(symbols)])(.*) : $(string) ] ;
    +        if $(m)
    +        {
    +            m += "" ;  # Supposedly a bug fix; borrowed from regex.split
    +            result = "$(result)$(m[1])$(escape-symbol)$(m[2])" ;
    +            string = $(m[3]) ;
    +        }
         }
    -  }
    -  string ?= "" ;
    -  result = "$(result)$(string)" ;
    -  return $(result) ;
    +    string ?= "" ;
    +    result = "$(result)$(string)" ;
    +    return $(result) ;
     }
     
    -# Replaces occurances of a match string in a given string. Returns the
    -# new string. The match string can be a regex expression.
    +
    +# Replaces occurrences of a match string in a given string and returns the new
    +# string. The match string can be a regex expression.
     #
     rule replace (
    -    string # The string to modify.
    -    match # The characters to replace.
    -    replacement # The string to replace with.
    +    string  # The string to modify.
    +    match  # The characters to replace.
    +    replacement  # The string to replace with.
         )
     {
         local result = "" ;
    @@ -125,9 +133,9 @@ rule replace (
         return $(result) ;
     }
     
    -# Replaces occurances of a match string in a given list of strings. 
    -# Returns the list of new strings. The match string can be a regex 
    -# expression.
    +
    +# Replaces occurrences of a match string in a given list of strings and returns
    +# a list of new strings. The match string can be a regex expression.
     #
     # list        - the list of strings to modify.
     # match       - the search expression.
    @@ -143,6 +151,7 @@ rule replace-list ( list * : match : replacement )
         return $(result) ;
     }
     
    +
     rule __test__ ( )
     {
         import assert ;
    @@ -153,28 +162,28 @@ rule __test__ ( )
         assert.result "" a "" b c : split "/a//b/c" / ;
         assert.result "" a "" b c "" : split "/a//b/c/" / ;
         assert.result "" a "" b c "" "" : split "/a//b/c//" / ;
    -    
    +
         assert.result a c b d
    -      : match (.)(.)(.)(.) : abcd : 1 3 2 4 ;
    -    
    +        : match (.)(.)(.)(.) : abcd : 1 3 2 4 ;
    +
         assert.result a b c d
    -      : match (.)(.)(.)(.) : abcd ;
    -    
    +        : match (.)(.)(.)(.) : abcd ;
    +
         assert.result ababab cddc
    -      : match ((ab)*)([cd]+) : abababcddc : 1 3 ;
    +        : match ((ab)*)([cd]+) : abababcddc : 1 3 ;
     
    -    assert.result a.h c.h 
    -      : transform  \"b.h\"  :  <(.*)> ;
    +    assert.result a.h c.h
    +        : transform  \"b.h\"  : <(.*)> ;
     
    -    assert.result a.h b.h c.h 
    -      : transform  \"b.h\"  :  <([^>]*)>|\"([^\"]*)\" : 1 2 ;
    +    assert.result a.h b.h c.h
    +        : transform  \"b.h\"  : <([^>]*)>|\"([^\"]*)\" : 1 2 ;
     
         assert.result "^"
    -      : escape "" : "&|()<>^" : "^" ;
    -    
    +        : escape "" : "&|()<>^" : "^" ;
    +
         assert.result ""
    -      : escape "" : "\\\"" : "\\" ;
    -    
    +        : escape "" : "\\\"" : "\\" ;
    +
         assert.result "string string " : replace "string string " " " " " ;
         assert.result " string string" : replace " string string" " " " " ;
         assert.result "string  string" : replace "string  string" " " " " ;
    diff --git a/v2/util/sequence.jam b/v2/util/sequence.jam
    index b190b8928..73919a65d 100644
    --- a/v2/util/sequence.jam
    +++ b/v2/util/sequence.jam
    @@ -204,8 +204,8 @@ rule unique ( list * : stable ? )
     }
     
     
    -# 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' if none is provided.
     #
     rule max-element ( elements + : ordered ? )
     {
    diff --git a/v2/util/utility.jam b/v2/util/utility.jam
    index 9dac70ba2..c46747f58 100644
    --- a/v2/util/utility.jam
    +++ b/v2/util/utility.jam
    @@ -1,66 +1,77 @@
    -# Copyright 2001, 2002 Dave Abrahams 
    -# Copyright 2002, 2003, 2004, 2005 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, 2004, 2005 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 "class" : is-instance ;
     import errors ;
     
    -rule ungrist ( names * )
    +
    +# For all elements of 'list' which do not already have 'suffix', add 'suffix'.
    +#
    +rule apply-default-suffix ( suffix : list * )
     {
         local result ;
    -    for local name in $(names)
    +    for local i in $(list)
         {
    -        local stripped = [ MATCH ^<(.*)>$ : $(name) ] ;
    -        if ! $(stripped)
    +        if $(i:S) = $(suffix)
             {
    -            errors.error "in ungrist" $(names) : $(name) is not of the form <.*> ;
    +            result += $(i) ;
    +        }
    +        else
    +        {
    +            result += $(i)$(suffix) ;
             }
    -        result += $(stripped) ;
         }
         return $(result) ;
     }
     
    +
    +# If 'name' contains a dot, returns the part before the last dot. If 'name'
    +# contains no dot, returns it unmodified.
    +#
    +rule basename ( name )
    +{
    +    if $(name:S)
    +    {
    +        name = $(name:B) ;
    +    }
    +    return $(name) ;
    +}
    +
    +
     # Return the file of the caller of the rule that called caller-file.
    +#
     rule caller-file ( )
     {
         local bt = [ BACKTRACE ] ;
         return $(bt[9]) ;
     }
     
    -# Returns the textual representation of argument. If it is a class
    -# instance, class its 'str' method. Otherwise, returns the argument.
    -rule str ( value )
    -{
    -    if [ is-instance $(value) ] 
    -    {
    -        return [ $(value).str ] ;
    -    }
    -    else
    -    {
    -        return $(value) ;
    -    }            
    -}
     
    -# Tests if 'a' is equal to 'b'. If 'a' is a class instance,
    -# calls its 'equal' method. Uses ordinary jam's comparison otherwise.
    +# Tests if 'a' is equal to 'b'. If 'a' is a class instance, calls its 'equal'
    +# method. Uses ordinary jam's comparison otherwise.
    +#
     rule equal ( a b )
     {
    -    if [ is-instance $(a) ] 
    +    if [ is-instance $(a) ]
         {
             return [ $(a).equal $(b) ] ;
         }
         else
         {
    -        if $(a) = $(b) 
    +        if $(a) = $(b)
             {
                 return true ;
             }
         }
     }
     
    -# Tests if 'a' is less than 'b'. If 'a' is a class instance, 
    -# calls its 'less' method. Uses ordinary jam's comparison otherwise.
    +
    +# Tests if 'a' is less than 'b'. If 'a' is a class instance, calls its 'less'
    +# method. Uses ordinary jam's comparison otherwise.
    +#
     rule less ( a b )
     {
         if [ is-instance $(a) ]
    @@ -76,66 +87,74 @@ rule less ( a b )
         }
     }
     
    -# For all elements of 'list' which do not already have 'suffix',
    -# add 'suffix'.
    -rule apply-default-suffix ( suffix : list * )
    +
    +# Returns the textual representation of argument. If it is a class instance,
    +# class its 'str' method. Otherwise, returns the argument.
    +#
    +rule str ( value )
    +{
    +    if [ is-instance $(value) ]
    +    {
    +        return [ $(value).str ] ;
    +    }
    +    else
    +    {
    +        return $(value) ;
    +    }
    +}
    +
    +
    +# Accepts a list of gristed values and returns them ungristed. Reports an error
    +# in case any of the passed parameters is not gristed, i.e. surrounded in angle
    +# brackets < and >.
    +#
    +rule ungrist ( names * )
     {
         local result ;
    -    for local i in $(list)
    +    for local name in $(names)
         {
    -        if $(i:S) = $(suffix)
    +        local stripped = [ MATCH ^<(.*)>$ : $(name) ] ;
    +        if ! $(stripped)
             {
    -            result += $(i) ;
    +            errors.error "in ungrist $(names) : $(name) is not of the form <.*>" ;
             }
    -        else
    -        {
    -            result += $(i)$(suffix) ;
    -        }        
    +        result += $(stripped) ;
         }
    -    return $(result) ;    
    +    return $(result) ;
     }
     
    -# If 'name' contains a dot, returns the part before the last dot.
    -# If 'name' contains no dot, returns it unmodified.
    -rule basename ( name )
    -{    
    -    if $(name:S)
    +
    +# If the passed value is quoted, unquotes it. Otherwise returns the value
    +# unchanged.
    +#
    +rule unquote ( value ? )
    +{
    +    local match-result = [ MATCH ^(\")(.*)(\")$ : $(value) ] ;
    +    if $(match-result)
         {
    -        name = $(name:B) ;
    +        return $(match-result[2]) ;
    +    }
    +    else
    +    {
    +        return $(value) ;
         }
    -    return $(name) ;
     }
     
     
    -
     rule __test__ ( )
     {
         import assert ;
         import "class" : new ;
    -    assert.result foo bar : ungrist   ;
    +    import errors : try catch ;
     
         assert.result 123 : str 123 ;
     
    -    class test-class__ 
    +    class test-class__
         {
    -        rule __init__ ( )
    -        {            
    -        }
    -        
    -        rule str ( )
    -        {
    -            return "str-test-class" ;
    -        }
    -
    -        rule less ( a )
    -        {
    -            return "yes, of course!" ;
    -        }
    -
    -        rule equal ( a )
    -        {
    -            return "not sure" ;
    -        }
    +        rule __init__ (   ) {                            }
    +        rule str      (   ) { return "str-test-class"  ; }
    +        rule less     ( a ) { return "yes, of course!" ; }
    +        rule equal    ( a ) { return "not sure"        ; }
         }
     
         assert.result "str-test-class" : str [ new test-class__ ] ;
    @@ -145,13 +164,72 @@ rule __test__ ( )
         assert.true equal 1 1 ;
         assert.false equal 1 2 ;
         assert.result "not sure" : equal [ new test-class__ ] 1 ;
    -    
    -    assert.result foo.lib foo.lib : apply-default-suffix .lib : foo.lib foo.lib ;
    -    
    +
    +    assert.result foo.lib foo.lib : apply-default-suffix .lib : foo.lib foo.lib
    +        ;
    +
         assert.result foo : basename foo ;
         assert.result foo : basename foo.so ;
         assert.result foo.so : basename foo.so.1 ;
    +
    +    assert.result         : unquote ;
    +    assert.result ""      : unquote "" ;
    +    assert.result foo     : unquote foo ;
    +    assert.result \"foo   : unquote \"foo ;
    +    assert.result foo\"   : unquote foo\" ;
    +    assert.result foo     : unquote \"foo\" ;
    +    assert.result \"foo\" : unquote \"\"foo\"\" ;
    +
    +    assert.result         : ungrist ;
    +    assert.result foo     : ungrist  ;
    +    assert.result    : ungrist <> ;
    +    assert.result foo bar : ungrist   ;
    +
    +    try ;
    +    {
    +        ungrist "" ;
    +    }
    +    catch "in ungrist  :  is not of the form <.*>" ;
    +
    +    try ;
    +    {
    +        ungrist <> ;
    +    }
    +    catch "in ungrist <> : <> is not of the form <.*>" ;
    +
    +    try ;
    +    {
    +        ungrist foo ;
    +    }
    +    catch "in ungrist foo : foo is not of the form <.*>" ;
    +
    +    try ;
    +    {
    +        ungrist " ;
    +
    +    try ;
    +    {
    +        ungrist foo> ;
    +    }
    +    catch "in ungrist foo> : foo> is not of the form <.*>" ;
    +
    +    try ;
    +    {
    +        ungrist foo bar ;
    +    }
    +    catch "in ungrist foo : foo is not of the form <.*>" ;
    +
    +    try ;
    +    {
    +        ungrist foo  ;
    +    }
    +    catch "in ungrist foo : foo is not of the form <.*>" ;
    +
    +    try ;
    +    {
    +        ungrist  bar ;
    +    }
    +    catch "in ungrist bar : bar is not of the form <.*>" ;
     }
    -
    -
    -