Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r86768 - in branches/release: . tools tools/build tools/build/v2 tools/build/v2/build tools/build/v2/doc/src tools/build/v2/engine tools/build/v2/test tools/build/v2/test/qt5 tools/build/v2/tools
From: steven_at_[hidden]
Date: 2013-11-19 14:52:02


Author: steven_watanabe
Date: 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013)
New Revision: 86768
URL: http://svn.boost.org/trac/boost/changeset/86768

Log:
Merge Boost.Build from the trunk.

Added:
   branches/release/tools/build/v2/test/builtin_readlink.py
      - copied unchanged from r84524, trunk/tools/build/v2/test/builtin_readlink.py
   branches/release/tools/build/v2/test/core_multifile_actions.py
      - copied unchanged from r86561, trunk/tools/build/v2/test/core_multifile_actions.py
   branches/release/tools/build/v2/test/libjpeg.py
      - copied unchanged from r84665, trunk/tools/build/v2/test/libjpeg.py
   branches/release/tools/build/v2/test/libpng.py
      - copied unchanged from r84498, trunk/tools/build/v2/test/libpng.py
   branches/release/tools/build/v2/test/libtiff.py
      - copied unchanged from r84665, trunk/tools/build/v2/test/libtiff.py
   branches/release/tools/build/v2/test/link.py
      - copied unchanged from r86709, trunk/tools/build/v2/test/link.py
   branches/release/tools/build/v2/test/source_order.py
      - copied unchanged from r86767, trunk/tools/build/v2/test/source_order.py
   branches/release/tools/build/v2/tools/libjpeg.jam
      - copied, changed from r84473, trunk/tools/build/v2/tools/libjpeg.jam
   branches/release/tools/build/v2/tools/libpng.jam
      - copied, changed from r84473, trunk/tools/build/v2/tools/libpng.jam
   branches/release/tools/build/v2/tools/libtiff.jam
      - copied, changed from r84473, trunk/tools/build/v2/tools/libtiff.jam
   branches/release/tools/build/v2/tools/link.jam
      - copied, changed from r84524, trunk/tools/build/v2/tools/link.jam
Deleted:
   branches/release/tools/build/v2/tools/jpeg.jam
   branches/release/tools/build/v2/tools/png.jam
   branches/release/tools/build/v2/tools/tiff.jam
Properties modified:
   branches/release/ (props changed)
   branches/release/tools/ (props changed)
   branches/release/tools/build/ (props changed)
   branches/release/tools/build/v2/ (props changed)
Text files modified:
   branches/release/tools/build/v2/build/configure.jam | 125 +++++++------
   branches/release/tools/build/v2/build/generators.jam | 2
   branches/release/tools/build/v2/build/version.jam | 4
   branches/release/tools/build/v2/build/virtual-target.jam | 3
   branches/release/tools/build/v2/doc/src/architecture.xml | 40 ++--
   branches/release/tools/build/v2/doc/src/extending.xml | 15
   branches/release/tools/build/v2/doc/src/faq.xml | 31 +++
   branches/release/tools/build/v2/doc/src/install.xml | 4
   branches/release/tools/build/v2/doc/src/overview.xml | 9
   branches/release/tools/build/v2/doc/src/recipes.xml | 2
   branches/release/tools/build/v2/doc/src/reference.xml | 7
   branches/release/tools/build/v2/doc/src/tasks.xml | 4
   branches/release/tools/build/v2/engine/builtins.c | 97 ++++++++++
   branches/release/tools/build/v2/engine/builtins.h | 1
   branches/release/tools/build/v2/engine/command.c | 37 ++++
   branches/release/tools/build/v2/engine/command.h | 29 +++
   branches/release/tools/build/v2/engine/compile.c | 49 ----
   branches/release/tools/build/v2/engine/filent.c | 13 +
   branches/release/tools/build/v2/engine/make.c | 29 +++
   branches/release/tools/build/v2/engine/make1.c | 353 ++++++++++++++++++++++++++++++---------
   branches/release/tools/build/v2/engine/patchlevel.h | 14
   branches/release/tools/build/v2/engine/rules.h | 7
   branches/release/tools/build/v2/engine/timestamp.h | 1
   branches/release/tools/build/v2/test/builtin_readlink.py | 24 ++
   branches/release/tools/build/v2/test/core_multifile_actions.py | 202 ++++++++++++++++++++++
   branches/release/tools/build/v2/test/libjpeg.py | 119 +++++++++++++
   branches/release/tools/build/v2/test/libpng.py | 119 +++++++++++++
   branches/release/tools/build/v2/test/libtiff.py | 119 +++++++++++++
   branches/release/tools/build/v2/test/link.py | 154 +++++++++++++++++
   branches/release/tools/build/v2/test/qt5/jamroot.jam | 2
   branches/release/tools/build/v2/test/source_order.py | 53 ++++++
   branches/release/tools/build/v2/test/test_all.py | 3
   branches/release/tools/build/v2/tools/boostbook.jam | 4
   /dev/null | 233 --------------------------
   branches/release/tools/build/v2/tools/libjpeg.jam | 7
   branches/release/tools/build/v2/tools/libpng.jam | 10
   branches/release/tools/build/v2/tools/libtiff.jam | 7
   branches/release/tools/build/v2/tools/link.jam | 36 ++--
   branches/release/tools/build/v2/tools/mpi.jam | 2
   branches/release/tools/build/v2/tools/msvc.jam | 12
   branches/release/tools/build/v2/tools/msvc.py | 2
   /dev/null | 226 -------------------------
   branches/release/tools/build/v2/tools/python.jam | 2
   branches/release/tools/build/v2/tools/qt5.jam | 2
   /dev/null | 230 --------------------------
   45 files changed, 1468 insertions(+), 976 deletions(-)

Modified: branches/release/tools/build/v2/build/configure.jam
==============================================================================
--- branches/release/tools/build/v2/build/configure.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/build/configure.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -123,10 +123,71 @@
     }
 }
 
+# Attempts to build a set of virtual targets
+rule try-build ( targets * : ps : what : retry ? )
+{
+ local cache-name = $(what) [ $(ps).raw ] ;
+ cache-name = $(cache-name:J=-) ;
+ local value = [ config-cache.get $(cache-name) ] ;
+
+ local result ;
+ local jam-targets ;
 
-# Attempt to build a metatarget named by 'metatarget-reference' in context of
-# 'project' with properties 'ps'. Returns non-empty value if build is OK.
-#
+ for local t in $(targets)
+ {
+ jam-targets += [ $(t).actualize ] ;
+ }
+
+ if $(value)
+ {
+ local x = [ PAD " - $(what)" : $(.width) ] ;
+ if $(value) = true
+ {
+ .$(what)-supported.$(ps) = yes ;
+ result = true ;
+ log-check-result "$(x) : yes (cached)" ;
+ }
+ else
+ {
+ log-check-result "$(x) : no (cached)" ;
+ }
+ }
+ else if ! UPDATE_NOW in [ RULENAMES ]
+ {
+ # Cannot determine. Assume existance.
+ }
+ else
+ {
+ local x = [ PAD " - $(what)" : $(.width) ] ;
+ if [ UPDATE_NOW $(jam-targets) :
+ $(.log-fd) : ignore-minus-n : ignore-minus-q ]
+ {
+ .$(what)-supported.$(ps) = yes ;
+ result = true ;
+ log-check-result "$(x) : yes" ;
+ }
+ else
+ {
+ log-check-result "$(x) : no" ;
+ }
+ }
+ if ! $(value)
+ {
+ if $(result)
+ {
+ config-cache.set $(cache-name) : true ;
+ }
+ else
+ {
+ config-cache.set $(cache-name) : false ;
+ }
+ }
+ return $(result) ;
+}
+
+# Attempt to build a metatarget named by 'metatarget-reference'
+# in context of 'project' with properties 'ps'.
+# Returns non-empty value if build is OK.
 rule builds-raw ( metatarget-reference : project : ps : what : retry ? )
 {
     local result ;
@@ -135,64 +196,14 @@
     {
         .$(what)-tested.$(ps) = true ;
 
- local cache-name = $(what) [ $(ps).raw ] ;
- cache-name = $(cache-name:J=-) ;
- local value = [ config-cache.get $(cache-name) ] ;
-
         local targets = [ targets.generate-from-reference
             $(metatarget-reference) : $(project) : $(ps) ] ;
 
- local jam-targets ;
- for local t in $(targets[2-])
- {
- jam-targets += [ $(t).actualize ] ;
- }
-
- if $(value)
- {
- local x = [ PAD " - $(what)" : $(.width) ] ;
- if $(value) = true
- {
- .$(what)-supported.$(ps) = yes ;
- result = true ;
- log-check-result "$(x) : yes (cached)" ;
- }
- else
- {
- log-check-result "$(x) : no (cached)" ;
- }
- }
- else if ! UPDATE_NOW in [ RULENAMES ]
- {
- # Cannot determine. Assume existance.
- }
- else
- {
- local x = [ PAD " - $(what)" : $(.width) ] ;
- if [ UPDATE_NOW $(jam-targets) :
- $(.log-fd) : ignore-minus-n : ignore-minus-q ]
- {
- .$(what)-supported.$(ps) = yes ;
- result = true ;
- log-check-result "$(x) : yes" ;
- }
- else
- {
- log-check-result "$(x) : no" ;
- }
- }
- if ! $(value)
- {
- if $(result)
- {
- config-cache.set $(cache-name) : true ;
- }
- else
- {
- config-cache.set $(cache-name) : false ;
- }
- }
+ result = [ try-build $(targets[2-]) : $(ps) : $(what) : $(retry) ] ;
+ .$(what)-supported.$(ps) = $(result) ;
+
         return $(result) ;
+
     }
     else
     {

Modified: branches/release/tools/build/v2/build/generators.jam
==============================================================================
--- branches/release/tools/build/v2/build/generators.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/build/generators.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -667,7 +667,7 @@
                     result += $(source) ;
                 }
             }
- return [ sequence.unique $(result) ] ;
+ return [ sequence.unique $(result) : stable ] ;
         }
     }
 

Modified: branches/release/tools/build/v2/build/version.jam
==============================================================================
--- branches/release/tools/build/v2/build/version.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/build/version.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -6,8 +6,8 @@
 import numbers ;
 
 
-.major = "2011" ;
-.minor = "12" ;
+.major = "2013" ;
+.minor = "05" ;
 
 
 rule boost-build ( )

Modified: branches/release/tools/build/v2/build/virtual-target.jam
==============================================================================
--- branches/release/tools/build/v2/build/virtual-target.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/build/virtual-target.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -1324,8 +1324,9 @@
         for local t in $(self.created-targets)
         {
             # Skip targets of the wrong type.
+ local type = [ $(t).type ] ;
             if ! $(target-type) ||
- [ type.is-derived [ $(t).type ] $(target-type) ]
+ ( $(type) && [ type.is-derived $(type) $(target-type) ] )
             {
                 result = [ sequence.merge $(result) : [ $(t).path ] ] ;
             }

Modified: branches/release/tools/build/v2/doc/src/architecture.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/architecture.xml Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/doc/src/architecture.xml 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -14,6 +14,9 @@
   <section id="bbv2.arch.overview">
     <title>Overview</title>
 
+ <!-- FIXME: the below does not mention engine at all, making rest of the
+ text confusing. Things like 'kernel' and 'util' don't have to be
+ mentioned at all. -->
     <para>
       Boost.Build implementation is structured in four different components:
     "kernel", "util", "build" and "tools". The first two are relatively
@@ -58,6 +61,7 @@
         from them.
         </para></listitem>
       </itemizedlist>
+
     </para>
 
     <para>
@@ -78,13 +82,14 @@
         <listitem><para>
           A generator appropriate for the build properties is selected and its
         <code>run</code> method is called. The method returns a list of virtual
- targets
+ targets.
         </para></listitem>
 
         <listitem><para>
- The targets are returned to the top level code. They are converted
- into bjam targets (via <code>virtual-target.actualize</code>) and passed
- to bjam for building.
+ The virtual targets are returned to the top level code, and for each instance,
+ the <literal>actualize</literal> method is called to setup nodes and updating
+ actions in the depenendency graph kepts inside Boost.Build engine. This dependency
+ graph is then updated, which runs necessary commands.
         </para></listitem>
       </orderedlist>
     </para>
@@ -163,11 +168,11 @@
       <title>Virtual targets</title>
 
       <para>
- Virtual targets correspond to atomic updatable entities. Each virtual
+ Virtual targets are atomic updatable entities. Each virtual
       target can be assigned an updating action -- instance of the
       <code>action</code> class. The action class, in turn, contains a list of
- source targets, properties, and a name of an bjam action which should be
- executed.
+ source targets, properties, and a name of an action which
+ should be executed.
       </para>
 
       <para>
@@ -178,12 +183,13 @@
       already been created. In that case, the preexisting target is returned.
       </para>
 
+ <!-- FIXME: the below 2 para are rubbish, must be totally rewritten. -->
       <para>
         When all virtual targets are produced, they are "actualized". This means
       that the real file names are computed, and the commands that should be run
       are generated. This is done by the <code>virtual-target.actualize</code>
       and <code>action.actualize</code> methods. The first is conceptually
- simple, while the second needs additional explanation. Commands in bjam
+ simple, while the second needs additional explanation. Commands in Boost.Build
       are generated in a two-stage process. First, a rule with an appropriate
       name (for example "gcc.compile") is called and is given a list of target
       names. The rule sets some variables, like "OPTIONS". After that, the
@@ -308,20 +314,14 @@
       <para>
         As stated above, it is possible to compile a C++ file multiple times,
       using different include paths. Therefore, include dependencies for those
- compilations can be different. The problem is that bjam does not allow
- multiple scans of the same target.
- </para>
-
- <para>
- The solution in Boost.Build is straightforward. When a virtual target is
- converted to a bjam target (via the
- <literal>virtual-target.actualize</literal> method), we specify the
- scanner object to be used. The actualize method will create different bjam
- targets for different scanners.
+ compilations can be different. The problem is that Boost.Build engine does
+ not allow multiple scans of the same target. To solve that, we pass the
+ scanner object when calling <literal>virtual-target.actualize</literal>
+ and it creates different engine targets for different scanners.
       </para>
 
       <para>
- For each Boost Jam target created with a scanner is created, a
+ For each engine target created with a specified scanner, a
       corresponding one is created without it. The updating action is
       associated with the scanner-less target, and the target with the scanner
       is made to depend on it. That way if sources for that action are touched,
@@ -355,7 +355,7 @@
         <listitem><simpara>
           If when compiling "a.cpp" there is an include of "a.h", the "dir"
         directory is on the include path, and a target called "a.h" will be
- generated in "dir", then bjam should discover the include, and create
+ generated in "dir", then Boost.Build should discover the include, and create
         "a.h" before compiling "a.cpp".
         </simpara></listitem>
 

Modified: branches/release/tools/build/v2/doc/src/extending.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/extending.xml Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/doc/src/extending.xml 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -181,7 +181,7 @@
         once with the same properties. Returning to different instance of <classname>file-target</classname>
         that correspond to the same file clearly will result in problems. Therefore, whenever
         returning targets you should pass them via the <code>virtual-target.register</code>
- function, besides allowing Boost Build to track which virtual targets
+ function, besides allowing Boost.Build to track which virtual targets
         got created for each metatarget, this will also replace targets with previously created identical
         ones, as necessary.<footnote><para>This create-then-register pattern is caused by limitations
         of the Boost.Jam language. Python port is likely to never create duplicate targets.</para></footnote>
@@ -613,7 +613,7 @@
         and the target type. When invoked, the generator will create a target
         of type <literal>CPP</literal> with a source target of
         type <literal>VERBATIM</literal> as the only source. But what command
- will be used to actually generate the file? In bjam, actions are
+ will be used to actually generate the file? In Boost.Build, actions are
         specified using named "actions" blocks and the name of the action
         block should be specified when creating targets. By convention,
         generators use the same name of the action block as their own id. So,
@@ -888,7 +888,7 @@
 
                 <listitem><para>if a feature is used to refer to a path relative
                 to the Jamfile, it must be a “path” feature. Such features will
- also get their values automatically converted to Boost Build's
+ also get their values automatically converted to Boost.Build's
                 internal path representation. For example, <code>include</code>
                 is a path feature.</para></listitem>
 
@@ -970,7 +970,7 @@
 
 
           <para> Note the <code>bind DEF_FILE</code> part. It tells
- bjam to translate the internal target name in
+ Boost.Build to translate the internal target name in
           <varname>DEF_FILE</varname> to a corresponding filename in
           the <code>link</code> action. Without it the expansion of
           <code>$(DEF_FILE)</code> would be a strange symbol that is
@@ -981,8 +981,7 @@
                targets in general, only source files." I'm not sure
                what I meant by that; maybe you can figure it out. -->
           <para>
- We are almost done, but we should stop for a small workaround. Add the following
- code to msvc.jam
+ We are almost done, except for adding the follwing code to <filename>msvc.jam</filename>:
 
 <programlisting>
 rule link
@@ -992,8 +991,8 @@
 </programlisting>
 <!-- You *must* explain the part in [...] above. It's completely opaque to the casual reader -->
 
- This is needed to accomodate some bug in bjam, which hopefully
- will be fixed one day.
+ This is a workaround for a bug in Boost.Build engine, which will hopefully
+ be fixed one day.
             <!-- This is *NOT* a bug!! Anyway, BBv2 shouild handle this automatically. Why doesn't it? -->
 </para></listitem>
 

Modified: branches/release/tools/build/v2/doc/src/faq.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/faq.xml Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/doc/src/faq.xml 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -446,6 +446,37 @@
 </programlisting>
     </para>
   </section>
+
+ <section id="bbv2.faq.names">
+ <title>
+ What is the difference between Boost.Build,
+ <filename>b2</filename>, <filename>bjam</filename> and Perforce Jam?
+ </title>
+
+ <para>
+ Boost.Build is the name of the complete build system. The executable that runs
+ it is <filename>b2</filename>. That executable is written in C and implements
+ performance-critical algorithms, like traversal of dependency graph and executing
+ commands. It also implements an interpreted language used to implement the rest of
+ Boost.Build. This executable is formally called "Boost.Build engine".
+ </para>
+
+ <para>
+ The Boost.Build engine is derived from an earlier build tool called Perforce Jam. Originally,
+ there were just minor changes, and the filename was <filename>bjam</filename>. Later on,
+ with more and more changes, the similarity of names because a disservice to users, and as of
+ Boost 1.47.0, the official name of the executable was changed to <filename>b2</filename>.
+ A copy named <filename>bjam</filename> is still created for compatibility,
+ but you are encouraged to use the new name in all cases.
+ </para>
+
+ <para>
+ Perforce Jam was an important foundation, and we gratefully acknowledge its influence,
+ but for users today, these tools share only some basics of the interpreted language.
+ </para>
+
+ </section>
+
 </chapter>
 
 <!--

Modified: branches/release/tools/build/v2/doc/src/install.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/install.xml Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/doc/src/install.xml 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -103,7 +103,7 @@
               </para>
 
               <para>Placing Boost.Build into <filename>/usr/share/boost-build</filename>
- will make sure that <command>bjam</command> will find Boost.Build
+ will make sure that <command>b2</command> will find Boost.Build
               without any additional setup.</para>
             </listitem>
 
@@ -120,7 +120,7 @@
         </para>
 
         <para>If those guidelines are met, users will be able to invoke
- <command>bjam</command> without any explicit configuration.
+ <command>b2/command> without any explicit configuration.
         </para>
 
     

Modified: branches/release/tools/build/v2/doc/src/overview.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/overview.xml Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/doc/src/overview.xml 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -14,9 +14,9 @@
     </para>
 
     <para>
- Boost.Build actually consists of two parts - Boost.Jam, a build engine
+ Boost.Build has two parts&emdash;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
+ that language. The chain of events when you type
       <command>b2</command> on the command line is as follows:
       <orderedlist>
         <listitem>
@@ -1183,7 +1183,9 @@
 </programlisting>
         </para>
 
- <para id="bbv2.overview.targets.requirements.conditional">Sometimes, particular relationships need to be maintained
+ <para id="bbv2.overview.targets.requirements.conditional">
+ <indexterm><primary>requirements</primary><secondary>conditional</secondary></indexterm>
+ Sometimes, particular relationships need to be maintained
         among a target's build properties. This can be achieved with
         <firstterm>conditional
         requirements</firstterm>. For example, you might want to set
@@ -1212,6 +1214,7 @@
         </para>
 
         <para id="bbv2.overview.targets.requirements.indirect">
+ <indexterm><primary>requirements</primary><secondary>indirect</secondary></indexterm>
           A more powerful variant of conditional requirements
           is <firstterm>indirect conditional requirements</firstterm>.
           You can provide a rule that will be called with the current build properties and can compute additional properties

Modified: branches/release/tools/build/v2/doc/src/recipes.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/recipes.xml Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/doc/src/recipes.xml 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -6,6 +6,6 @@
        future or FAQ completely supercedes it. -->
 
   <appendix id="bbv2.recipies">
- <title>Boost Build System V2 recipes</title>
+ <title>Boost.Build System V2 recipes</title>
 
   </appendix>

Modified: branches/release/tools/build/v2/doc/src/reference.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/reference.xml Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/doc/src/reference.xml 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -17,8 +17,9 @@
     <section id="bbv2.reference.init">
       <title>Initialization</title>
 
- <para>bjam's first job upon startup is to load the Jam code that
- implements the build system. To do this, it searches for a file
+ <para>
+ Immediately upon starting, the Boost.Build engine (<command>b2</command>)
+ loads the Jam code that implements the build system. To do this, it searches for a file
         called <filename>boost-build.jam</filename>, first in the invocation directory, then
         in its parent and so forth up to the filesystem root, and finally
         in the directories specified by the environment variable
@@ -741,7 +742,7 @@
 
           <para>
             <emphasis role="bold">Note:</emphasis> Due to some internal details
- in the current Boost Build implementation it is not possible to have
+ 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

Modified: branches/release/tools/build/v2/doc/src/tasks.xml
==============================================================================
--- branches/release/tools/build/v2/doc/src/tasks.xml Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/doc/src/tasks.xml 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -447,8 +447,8 @@
       <varname>args</varname> and <varname>input-files</varname> as command-line
       arguments. The <varname>args</varname> parameter is passed verbatim and
       the values of the <varname>input-files</varname> parameter are treated as
- paths relative to containing Jamfile, and are adjusted if <command>bjam
- </command> is invoked from a different directory. The
+ paths relative to containing Jamfile, and are adjusted if <command>b2</command>
+ is invoked from a different directory. The
       <code>run-fail</code> rule is identical to the <code>run</code> rule,
       except that it expects that the run fails.
     </para>

Modified: branches/release/tools/build/v2/engine/builtins.c
==============================================================================
--- branches/release/tools/build/v2/engine/builtins.c Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/builtins.c 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -29,6 +29,10 @@
 
 #include <ctype.h>
 
+#ifdef OS_NT
+#include <windows.h>
+#endif
+
 #if defined(USE_EXECUNIX)
 # include <sys/types.h>
 # include <sys/wait.h>
@@ -425,6 +429,11 @@
         char const * args [] = { "path", 0 };
         bind_builtin( "MAKEDIR", builtin_makedir, 0, args );
     }
+
+ {
+ const char * args [] = { "path", 0 };
+ bind_builtin( "READLINK", builtin_readlink, 0, args );
+ }
 
     /* Initialize builtin modules. */
     init_set();
@@ -1827,6 +1836,94 @@
         : list_new( object_copy( list_front( path ) ) );
 }
 
+LIST *builtin_readlink( FRAME * frame, int flags )
+{
+ const char * path = object_str( list_front( lol_get( frame->args, 0 ) ) );
+#ifdef OS_NT
+
+ /* This struct is declared in ntifs.h which is
+ * part of the Windows Driver Kit.
+ */
+ typedef struct _REPARSE_DATA_BUFFER {
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union {
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[ 1 ];
+ } SymbolicLinkReparseBuffer;
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[ 1 ];
+ } MountPointReparseBuffer;
+ struct {
+ UCHAR DataBuffer[ 1 ];
+ } GenericReparseBuffer;
+ };
+ } REPARSE_DATA_BUFFER;
+
+ HANDLE hLink = CreateFileA( path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL );
+ DWORD n;
+ union {
+ REPARSE_DATA_BUFFER reparse;
+ char data[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ } buf;
+ int okay = DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, &buf, sizeof(buf), &n, NULL);
+
+ CloseHandle( hLink );
+
+ if (okay && buf.reparse.ReparseTag == IO_REPARSE_TAG_SYMLINK )
+ {
+ int index = buf.reparse.SymbolicLinkReparseBuffer.SubstituteNameOffset / 2;
+ int length = buf.reparse.SymbolicLinkReparseBuffer.SubstituteNameLength / 2;
+ char cbuf[MAX_PATH + 1];
+ int numchars = WideCharToMultiByte( CP_ACP, 0, buf.reparse.SymbolicLinkReparseBuffer.PathBuffer + index, length, cbuf, sizeof(cbuf), NULL, NULL );
+ if( numchars >= sizeof(cbuf) )
+ {
+ return 0;
+ }
+ cbuf[numchars] = '\0';
+ return list_new( object_new( cbuf ) );
+ }
+ return 0;
+#else
+ char static_buf[256];
+ char * buf = static_buf;
+ size_t bufsize = 256;
+ LIST * result = 0;
+ while (1) {
+ ssize_t len = readlink( path, buf, bufsize );
+ if ( len < 0 )
+ {
+ break;
+ }
+ else if ( len < bufsize )
+ {
+ buf[ len ] = '\0';
+ result = list_new( object_new( buf ) );
+ break;
+ }
+ if ( buf != static_buf )
+ BJAM_FREE( buf );
+ bufsize *= 2;
+ buf = BJAM_MALLOC( bufsize );
+ }
+
+ if ( buf != static_buf )
+ BJAM_FREE( buf );
+
+ return result;
+#endif
+}
+
 
 #ifdef HAVE_PYTHON
 

Modified: branches/release/tools/build/v2/engine/builtins.h
==============================================================================
--- branches/release/tools/build/v2/engine/builtins.h Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/builtins.h 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -63,6 +63,7 @@
 LIST *builtin_precious( FRAME * frame, int flags );
 LIST *builtin_self_path( FRAME * frame, int flags );
 LIST *builtin_makedir( FRAME * frame, int flags );
+LIST *builtin_readlink( FRAME * frame, int flags );
 
 void backtrace( FRAME *frame );
 extern int last_update_now_status;

Modified: branches/release/tools/build/v2/engine/command.c
==============================================================================
--- branches/release/tools/build/v2/engine/command.c Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/command.c 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -24,6 +24,37 @@
 
 
 /*
+ * cmdlist_append_cmd
+ */
+CMDLIST * cmdlist_append_cmd( CMDLIST * l, CMD * cmd )
+{
+ CMDLIST * result = (CMDLIST *)BJAM_MALLOC( sizeof( CMDLIST ) );
+ result->iscmd = 1;
+ result->next = l;
+ result->impl.cmd = cmd;
+ return result;
+}
+
+CMDLIST * cmdlist_append_target( CMDLIST * l, TARGET * t )
+{
+ CMDLIST * result = (CMDLIST *)BJAM_MALLOC( sizeof( CMDLIST ) );
+ result->iscmd = 0;
+ result->next = l;
+ result->impl.t = t;
+ return result;
+}
+
+void cmdlist_free( CMDLIST * l )
+{
+ while ( l )
+ {
+ CMDLIST * tmp = l->next;
+ BJAM_FREE( l );
+ l = tmp;
+ }
+}
+
+/*
  * cmd_new() - return a new CMD.
  */
 
@@ -37,6 +68,10 @@
     cmd->shell = shell;
     cmd->next = 0;
     cmd->noop = 0;
+ cmd->asynccnt = 1;
+ cmd->status = 0;
+ cmd->lock = NULL;
+ cmd->unlock = NULL;
 
     lol_init( &cmd->args );
     lol_add( &cmd->args, targets );
@@ -62,9 +97,11 @@
 
 void cmd_free( CMD * cmd )
 {
+ cmdlist_free( cmd->next );
     lol_free( &cmd->args );
     list_free( cmd->shell );
     string_free( cmd->buf );
+ freetargets( cmd->unlock );
     BJAM_FREE( (void *)cmd );
 }
 

Modified: branches/release/tools/build/v2/engine/command.h
==============================================================================
--- branches/release/tools/build/v2/engine/command.h Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/command.h 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -46,14 +46,41 @@
 
 
 typedef struct _cmd CMD;
+
+/*
+ * A list whose elements are either TARGETS or CMDS.
+ * CMDLIST is used only by CMD. A TARGET means that
+ * the CMD is the last updating action required to
+ * build the target. A CMD is the next CMD required
+ * to build the same target. (Note that a single action
+ * can update more than one target, so the CMDs form
+ * a DAG, not a straight linear list.)
+ */
+typedef struct _cmdlist {
+ struct _cmdlist * next;
+ union {
+ CMD * cmd;
+ TARGET * t;
+ } impl;
+ char iscmd;
+} CMDLIST;
+
+CMDLIST * cmdlist_append_cmd( CMDLIST *, CMD * );
+CMDLIST * cmdlist_append_target( CMDLIST *, TARGET * );
+void cmd_list_free( CMDLIST * );
+
 struct _cmd
 {
- CMD * next;
+ CMDLIST * next;
     RULE * rule; /* rule->actions contains shell script */
     LIST * shell; /* $(JAMSHELL) value */
     LOL args; /* LISTs for $(<), $(>) */
     string buf[ 1 ]; /* actual commands */
     int noop; /* no-op commands should be faked instead of executed */
+ int asynccnt; /* number of outstanding dependencies */
+ TARGETS * lock; /* semaphores that are required by this cmd. */
+ TARGETS * unlock; /* semaphores that are released when this cmd finishes. */
+ char status; /* the command status */
 };
 
 CMD * cmd_new

Modified: branches/release/tools/build/v2/engine/compile.c
==============================================================================
--- branches/release/tools/build/v2/engine/compile.c Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/compile.c 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -117,56 +117,17 @@
         action->refs = 1;
 
         /* If we have a group of targets all being built using the same action
- * then we must not allow any of them to be used as sources unless they
- * are all up to date and their action does not need to be run or their
- * action has had a chance to finish its work and build all of them
- * anew.
- *
- * Without this it might be possible, in case of a multi-process build,
- * for their action, triggered to building one of the targets, to still
- * be running when another target in the group reports as done in order
- * to avoid triggering the same action again and gets used prematurely.
- *
- * As a quick-fix to achieve this effect we make all the targets list
- * each other as 'included targets'. More precisely, we mark the first
- * listed target as including all the other targets in the list and vice
- * versa. This makes anyone depending on any of those targets implicitly
- * depend on all of them, thus making sure none of those targets can be
- * used as sources until all of them have been built. Note that direct
- * dependencies could not have been used due to the 'circular
- * dependency' issue.
- *
- * TODO: Although the current implementation solves the problem of one
- * of the targets getting used before its action completes its work, it
- * also forces the action to run whenever any of the targets in the
- * group is not up to date even though some of them might not actually
- * be used by the targets being built. We should see how we can
- * correctly recognize such cases and use that to avoid running the
- * action if possible and not rebuild targets not actually depending on
- * targets that are not up to date.
- *
- * TODO: Current solution using fake INCLUDES relations may cause
- * actions to be run when the affected targets are built by multiple
- * actions. E.g. if we have the following actions registered in the
- * order specified:
- * (I) builds targets A & B
- * (II) builds target B
- * and we want to build a target depending on target A, then both
- * actions (I) & (II) will be run, even though the second one does not
- * have any direct relationship to target A. Consider whether this is
- * desired behaviour or not. It could be that Boost Build should (or
- * possibly already does) run all actions registered for a given target
- * if any of them needs to be run in which case our INCLUDES relations
- * are not actually causing any actions to be run that would not have
- * been run without them.
+ * and any of these targets is updated, then we have to consider them
+ * all to be out-dated. We do this by adding a REBUILDS in both directions
+ * between the first target and all the other targets.
          */
         if ( action->targets )
         {
             TARGET * const t0 = action->targets->target;
             for ( t = action->targets->next; t; t = t->next )
             {
- target_include( t->target, t0 );
- target_include( t0, t->target );
+ t->target->rebuilds = targetentry( t->target->rebuilds, t0 );
+ t0->rebuilds = targetentry( t0->rebuilds, t->target );
             }
         }
 

Modified: branches/release/tools/build/v2/engine/filent.c
==============================================================================
--- branches/release/tools/build/v2/engine/filent.c Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/filent.c 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -122,6 +122,19 @@
                 ff->is_file = !ff->is_dir;
                 ff->exists = 1;
                 timestamp_from_filetime( &ff->time, &finfo.ftLastWriteTime );
+ // Use the timestamp of the link target, not the link itself
+ // (i.e. stat instead of lstat)
+ if ( finfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT )
+ {
+ HANDLE hLink = CreateFileA( pathname->value, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
+ BY_HANDLE_FILE_INFORMATION target_finfo[ 1 ];
+ if ( hLink != INVALID_HANDLE_VALUE && GetFileInformationByHandle( hLink, target_finfo ) )
+ {
+ ff->is_file = target_finfo->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? 0 : 1;
+ ff->is_dir = target_finfo->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? 1 : 0;
+ timestamp_from_filetime( &ff->time, &target_finfo->ftLastWriteTime );
+ }
+ }
             }
         }
         while ( FindNextFile( findHandle, &finfo ) );

Modified: branches/release/tools/build/v2/engine/make.c
==============================================================================
--- branches/release/tools/build/v2/engine/make.c Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/make.c 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -161,6 +161,8 @@
  * make0() to be updated.
  */
 
+static void force_rebuilds( TARGET * t );
+
 static void update_dependants( TARGET * t )
 {
     TARGETS * q;
@@ -190,6 +192,8 @@
                 update_dependants( p );
         }
     }
+ /* Make sure that rebuilds can be chained. */
+ force_rebuilds( t );
 }
 
 
@@ -676,7 +680,30 @@
     else
         fate = t->fate;
 
- /* Step 4g: If this target needs to be built, force rebuild everything in
+ /*
+ * Step 4g: If this target needs to be built, make0 all targets
+ * that are updated by the same actions used to update this target.
+ * These have already been marked as REBUILDS, and make1 has
+ * special handling for them. We just need to make sure that
+ * they get make0ed.
+ */
+ if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) )
+ {
+ ACTIONS * a;
+ TARGETS * c;
+ for ( a = t->actions; a; a = a->next )
+ {
+ for ( c = a->action->targets; c; c = c->next )
+ {
+ if ( c->target->fate == T_FATE_INIT )
+ {
+ make0( c->target, ptime, depth + 1, counts, anyhow, rescanning );
+ }
+ }
+ }
+ }
+
+ /* Step 4h: If this target needs to be built, force rebuild everything in
      * its rebuilds list.
      */
     if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) )

Modified: branches/release/tools/build/v2/engine/make1.c
==============================================================================
--- branches/release/tools/build/v2/engine/make1.c Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/make1.c 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -63,6 +63,12 @@
 static void make1bind ( TARGET * );
 static TARGET * make1findcycle ( TARGET * );
 static void make1breakcycle( TARGET *, TARGET * cycle_root );
+static void push_cmds( CMDLIST * cmds, int status );
+static int cmd_sem_lock( TARGET * t );
+static void cmd_sem_unlock( TARGET * t );
+
+static int targets_contains( TARGETS * l, TARGET * t );
+static int targets_equal( TARGETS * l1, TARGETS * l2 );
 
 /* Ugly static - it is too hard to carry it through the callbacks. */
 
@@ -372,33 +378,16 @@
     TARGET * failed = 0;
     char const * failed_name = "dependencies";
 
+ pop_state( &state_stack );
+
     /* If any dependencies are still outstanding, wait until they signal their
      * completion by pushing this same state for their parent targets.
      */
     if ( --t->asynccnt )
     {
- pop_state( &state_stack );
         return;
     }
 
- /* Try to aquire a semaphore. If it is locked, wait until the target that
- * locked it is built and signals completition.
- */
-#ifdef OPT_SEMAPHORE
- if ( t->semaphore && t->semaphore->asynccnt )
- {
- /* Append 't' to the list of targets waiting on semaphore. */
- t->semaphore->parents = targetentry( t->semaphore->parents, t );
- t->asynccnt++;
-
- if ( DEBUG_EXECCMD )
- printf( "SEM: %s is busy, delaying launch of %s\n",
- object_str( t->semaphore->name ), object_str( t->name ) );
- pop_state( &state_stack );
- return;
- }
-#endif
-
     /* Now ready to build target 't', if dependencies built OK. */
 
     /* Collect status from dependencies. If -n was passed then act as though all
@@ -492,28 +481,19 @@
             abort();
         }
 
-#ifdef OPT_SEMAPHORE
- /* If there is a semaphore, indicate that it is in use. */
- if ( t->semaphore )
- {
- ++t->semaphore->asynccnt;
- if ( DEBUG_EXECCMD )
- printf( "SEM: %s now used by %s\n", object_str( t->semaphore->name
- ), object_str( t->name ) );
- }
-#endif
-
     /* Proceed to MAKE1C to begin executing the chain of commands prepared for
      * building the target. If we are not going to build the target (e.g. due to
      * dependency failures or no commands needing to be run) the chain will be
      * empty and MAKE1C processing will directly signal the target's completion.
      */
- /* Implementation note:
- * Morfing the current state on the stack instead of popping it and
- * pushing a new one is a slight optimization with no side-effects since we
- * pushed no other states while processing this one.
- */
- pState->curstate = T_STATE_MAKE1C;
+
+ if ( t->cmds == NULL || --( ( CMD * )t->cmds )->asynccnt == 0 )
+ push_state( &state_stack, t, NULL, T_STATE_MAKE1C );
+ else if ( DEBUG_EXECCMD )
+ {
+ CMD * cmd = ( CMD * )t->cmds;
+ printf( "Delaying %s %s: %d targets not ready\n", object_str( cmd->rule->name ), object_str( t->boundname ), cmd->asynccnt );
+ }
 }
 
 
@@ -534,7 +514,7 @@
     TARGET * const t = pState->t;
     CMD * const cmd = (CMD *)t->cmds;
 
- if ( cmd && t->status == EXEC_CMD_OK )
+ if ( cmd )
     {
         /* Pop state first in case something below (e.g. exec_cmd(), exec_wait()
          * or make1c_closure()) pushes a new state. Note that we must not access
@@ -543,6 +523,21 @@
          */
         pop_state( &state_stack );
 
+ if ( cmd->status != EXEC_CMD_OK )
+ {
+ t->cmds = NULL;
+ push_cmds( cmd->next, cmd->status );
+ cmd_free( cmd );
+ return;
+ }
+
+#ifdef OPT_SEMAPHORE
+ if ( ! cmd_sem_lock( t ) )
+ {
+ return;
+ }
+#endif
+
         /* Increment the jobs running counter. */
         ++cmdsrunning;
 
@@ -575,14 +570,6 @@
     {
         ACTIONS * actions;
 
- /* Collect status from actions, and distribute it as well. */
- for ( actions = t->actions; actions; actions = actions->next )
- if ( actions->action->status > t->status )
- t->status = actions->action->status;
- for ( actions = t->actions; actions; actions = actions->next )
- if ( t->status > actions->action->status )
- actions->action->status = t->status;
-
         /* Tally success/failure for those we tried to update. */
         if ( t->progress == T_MAKE_RUNNING )
             switch ( t->status )
@@ -677,38 +664,6 @@
                     push_state( &temp_stack, c->target, NULL, T_STATE_MAKE1B );
             }
 
-#ifdef OPT_SEMAPHORE
- /* If there is a semaphore, it is now free. */
- if ( t->semaphore )
- {
- assert( t->semaphore->asynccnt == 1 );
- --t->semaphore->asynccnt;
-
- if ( DEBUG_EXECCMD )
- printf( "SEM: %s is now free\n", object_str(
- t->semaphore->name ) );
-
- /* If anything is waiting, notify the next target. There is no
- * point in notifying all waiting targets, since they will be
- * notified again.
- */
- if ( t->semaphore->parents )
- {
- TARGETS * first = t->semaphore->parents;
- t->semaphore->parents = first->next;
- if ( first->next )
- first->next->tail = first->tail;
-
- if ( DEBUG_EXECCMD )
- printf( "SEM: placing %s on stack\n", object_str(
- first->target->name ) );
- push_state( &temp_stack, first->target, NULL, T_STATE_MAKE1B
- );
- BJAM_FREE( first );
- }
- }
-#endif
-
             /* Must pop state before pushing any more. */
             pop_state( &state_stack );
 
@@ -945,12 +900,57 @@
         }
     }
 
+#ifdef OPT_SEMAPHORE
+ /* Release any semaphores used by this action. */
+ cmd_sem_unlock( t );
+#endif
+
     /* Free this command and push the MAKE1C state to execute the next one
      * scheduled for building this same target.
      */
- t->cmds = (char *)cmd_next( cmd );
+ t->cmds = NULL;
+ push_cmds( cmd->next, t->status );
     cmd_free( cmd );
- push_state( &state_stack, t, NULL, T_STATE_MAKE1C );
+}
+
+/* push the next MAKE1C state after a command is run. */
+static void push_cmds( CMDLIST * cmds, int status )
+{
+ CMDLIST * cmd_iter;
+ for( cmd_iter = cmds; cmd_iter; cmd_iter = cmd_iter->next )
+ {
+ if ( cmd_iter->iscmd )
+ {
+ CMD * next_cmd = cmd_iter->impl.cmd;
+ /* Propagate the command status. */
+ if ( next_cmd->status < status )
+ next_cmd->status = status;
+ if ( --next_cmd->asynccnt == 0 )
+ {
+ /* Select the first target associated with the action.
+ * This is safe because sibling CMDs cannot have targets
+ * in common.
+ */
+ TARGET * first_target = bindtarget( list_front( lol_get( &next_cmd->args, 0 ) ) );
+ first_target->cmds = (char *)next_cmd;
+ push_state( &state_stack, first_target, NULL, T_STATE_MAKE1C );
+ }
+ else if ( DEBUG_EXECCMD )
+ {
+ TARGET * first_target = bindtarget( list_front( lol_get( &next_cmd->args, 0 ) ) );
+ printf( "Delaying %s %s: %d targets not ready\n", object_str( next_cmd->rule->name ), object_str( first_target->boundname ), next_cmd->asynccnt );
+ }
+ }
+ else
+ {
+ /* This is a target that we're finished updating */
+ TARGET * updated_target = cmd_iter->impl.t;
+ if ( updated_target->status < status )
+ updated_target->status = status;
+ updated_target->cmds = NULL;
+ push_state( &state_stack, updated_target, NULL, T_STATE_MAKE1C );
+ }
+ }
 }
 
 
@@ -995,15 +995,14 @@
 static CMD * make1cmds( TARGET * t )
 {
     CMD * cmds = 0;
- CMD * * cmds_next = &cmds;
+ CMD * last_cmd;
     LIST * shell = L0;
     module_t * settings_module = 0;
     TARGET * settings_target = 0;
     ACTIONS * a0;
     int const running_flag = globs.noexec ? A_RUNNING_NOEXEC : A_RUNNING;
 
- /* Step through actions. Actions may be shared with other targets or grouped
- * using RULE_TOGETHER, so actions already seen are skipped.
+ /* Step through actions.
      */
     for ( a0 = t->actions; a0; a0 = a0->next )
     {
@@ -1014,11 +1013,36 @@
         LIST * ns;
         ACTIONS * a1;
 
- /* Only do rules with commands to execute. If this action has already
- * been executed, use saved status.
+ /* Only do rules with commands to execute.
          */
- if ( !actions || a0->action->running >= running_flag )
+ if ( !actions )
+ continue;
+
+ if ( a0->action->running >= running_flag )
+ {
+ CMD * first;
+ /* If this action was skipped either because it was
+ * combined with another action by RULE_TOGETHER, or
+ * because all of its sources were filtered out,
+ * then we don't have anything to do here.
+ */
+ if ( a0->action->first_cmd == NULL )
+ continue;
+ /* This action has already been processed for another target.
+ * Just set up the dependency graph correctly and move on.
+ */
+ first = a0->action->first_cmd;
+ if( cmds )
+ {
+ last_cmd->next = cmdlist_append_cmd( last_cmd->next, first );
+ }
+ else
+ {
+ cmds = first;
+ }
+ last_cmd = a0->action->last_cmd;
             continue;
+ }
 
         a0->action->running = running_flag;
 
@@ -1031,7 +1055,8 @@
         if ( actions->flags & RULE_TOGETHER )
             for ( a1 = a0->next; a1; a1 = a1->next )
                 if ( a1->action->rule == rule &&
- a1->action->running < running_flag )
+ a1->action->running < running_flag &&
+ targets_equal( a0->action->targets, a1->action->targets ) )
                 {
                     ns = make1list( ns, a1->action->sources, actions->flags );
                     a1->action->running = running_flag;
@@ -1076,8 +1101,12 @@
             int const length = list_length( ns );
             int start = 0;
             int chunk = length;
+ int cmd_count = 0;
             LIST * cmd_targets = L0;
             LIST * cmd_shell = L0;
+ TARGETS * semaphores = NULL;
+ TARGETS * targets_iter;
+ int unique_targets;
             do
             {
                 CMD * cmd;
@@ -1138,8 +1167,20 @@
                 if ( accept_command )
                 {
                     /* Chain it up. */
- *cmds_next = cmd;
- cmds_next = &cmd->next;
+ if ( cmds )
+ {
+ last_cmd->next = cmdlist_append_cmd( last_cmd->next, cmd );
+ last_cmd = cmd;
+ }
+ else
+ {
+ cmds = last_cmd = cmd;
+ }
+
+ if ( cmd_count++ == 0 )
+ {
+ a0->action->first_cmd = cmd;
+ }
 
                     /* Mark lists we need recreated for the next command since
                      * they got consumed by the cmd object.
@@ -1160,6 +1201,39 @@
                     start += chunk;
             }
             while ( start < length );
+
+ /* Record the end of the actions cmds */
+ a0->action->last_cmd = last_cmd;
+
+ unique_targets = 0;
+ for ( targets_iter = a0->action->targets; targets_iter; targets_iter = targets_iter->next )
+ {
+ if ( targets_contains( targets_iter->next, targets_iter->target ) )
+ continue;
+ /* Add all targets produced by the action to the update list. */
+ push_state( &state_stack, targets_iter->target, NULL, T_STATE_MAKE1A );
+ ++unique_targets;
+ }
+ /* We need to wait until all the targets agree that
+ * it's okay to run this action.
+ */
+ ( ( CMD * )a0->action->first_cmd )->asynccnt = unique_targets;
+
+#if OPT_SEMAPHORE
+ /* Collect semaphores */
+ for ( targets_iter = a0->action->targets; targets_iter; targets_iter = targets_iter->next )
+ {
+ TARGET * sem = targets_iter->target->semaphore;
+ if ( sem )
+ {
+ TARGETS * semiter;
+ if ( ! targets_contains( semaphores, sem ) )
+ semaphores = targetentry( semaphores, sem );
+ }
+ }
+ ( ( CMD * )a0->action->first_cmd )->lock = semaphores;
+ ( ( CMD * )a0->action->last_cmd )->unlock = semaphores;
+#endif
         }
 
         /* These were always copied when used. */
@@ -1171,6 +1245,11 @@
         freesettings( boundvars );
     }
 
+ if ( cmds )
+ {
+ last_cmd->next = cmdlist_append_target( last_cmd->next, t );
+ }
+
     swap_settings( &settings_module, &settings_target, 0, 0 );
     return cmds;
 }
@@ -1281,3 +1360,101 @@
     t->binding = timestamp_empty( &t->time ) ? T_BIND_MISSING : T_BIND_EXISTS;
     popsettings( root_module(), t->settings );
 }
+
+
+static int targets_contains( TARGETS * l, TARGET * t )
+{
+ for ( ; l; l = l->next )
+ {
+ if ( t == l->target )
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int targets_equal( TARGETS * l1, TARGETS * l2 )
+{
+ for ( ; l1 && l2; l1 = l1->next, l2 = l2->next )
+ {
+ if ( l1->target != l2->target )
+ return 0;
+ }
+ return !l1 && !l2;
+}
+
+
+#ifdef OPT_SEMAPHORE
+
+static int cmd_sem_lock( TARGET * t )
+{
+ CMD * cmd = (CMD *)t->cmds;
+ TARGETS * iter;
+ /* Check whether all the semaphores required for updating
+ * this target are free.
+ */
+ for ( iter = cmd->lock; iter; iter = iter->next )
+ {
+ if ( iter->target->asynccnt > 0 )
+ {
+ if ( DEBUG_EXECCMD )
+ printf( "SEM: %s is busy, delaying launch of %s\n",
+ object_str( iter->target->name ), object_str( t->name ) );
+ iter->target->parents = targetentry( iter->target->parents, t );
+ return 0;
+ }
+ }
+ /* Lock the semaphores. */
+ for ( iter = cmd->lock; iter; iter = iter->next )
+ {
+ ++iter->target->asynccnt;
+ if ( DEBUG_EXECCMD )
+ printf( "SEM: %s now used by %s\n", object_str( iter->target->name
+ ), object_str( t->name ) );
+ }
+ /* A cmd only needs to be locked around its execution.
+ * clearing cmd->lock here makes it safe to call cmd_sem_lock
+ * twice.
+ */
+ cmd->lock = NULL;
+ return 1;
+}
+
+static void cmd_sem_unlock( TARGET * t )
+{
+ CMD * cmd = ( CMD * )t->cmds;
+ TARGETS * iter;
+ /* Release the semaphores. */
+ for ( iter = cmd->unlock; iter; iter = iter->next )
+ {
+ if ( DEBUG_EXECCMD )
+ printf( "SEM: %s is now free\n", object_str(
+ iter->target->name ) );
+ --iter->target->asynccnt;
+ assert( iter->target->asynccnt <= 0 );
+ }
+ for ( iter = cmd->unlock; iter; iter = iter->next )
+ {
+ /* Find a waiting target that's ready */
+ while ( iter->target->parents )
+ {
+ TARGETS * first = iter->target->parents;
+ TARGET * t1 = first->target;
+
+ /* Pop the first waiting CMD */
+ if ( first->next )
+ first->next->tail = first->tail;
+ iter->target->parents = first->next;
+ BJAM_FREE( first );
+
+ if ( cmd_sem_lock( t1 ) )
+ {
+ push_state( &state_stack, t1, NULL, T_STATE_MAKE1C );
+ break;
+ }
+ }
+ }
+}
+
+#endif

Modified: branches/release/tools/build/v2/engine/patchlevel.h
==============================================================================
--- branches/release/tools/build/v2/engine/patchlevel.h Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/patchlevel.h 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -7,11 +7,11 @@
 /* Keep JAMVERSYM in sync with VERSION. */
 /* It can be accessed as $(JAMVERSION) in the Jamfile. */
 
-#define VERSION_MAJOR 2011
+#define VERSION_MAJOR 2013
 #define VERSION_MINOR 12
-#define VERSION_PATCH 1
-#define VERSION_MAJOR_SYM "2011"
-#define VERSION_MINOR_SYM "12"
-#define VERSION_PATCH_SYM "01"
-#define VERSION "2011.12.1"
-#define JAMVERSYM "JAMVERSION=2011.12"
+#define VERSION_PATCH 0
+#define VERSION_MAJOR_SYM "2013"
+#define VERSION_MINOR_SYM "05"
+#define VERSION_PATCH_SYM "00"
+#define VERSION "2013.05"
+#define JAMVERSYM "JAMVERSION=2013.05"

Modified: branches/release/tools/build/v2/engine/rules.h
==============================================================================
--- branches/release/tools/build/v2/engine/rules.h Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/rules.h 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -92,8 +92,13 @@
 #define A_INIT 0
 #define A_RUNNING_NOEXEC 1
 #define A_RUNNING 2
- char status; /* see TARGET status */
     int refs;
+
+ /* WARNING: These variables are used to pass state required by make1cmds and
+ * are not valid anywhere else.
+ */
+ void * first_cmd; /* Pointer to the first CMD created by this action */
+ void * last_cmd; /* Pointer to the last CMD created by this action */
 };
 
 /* SETTINGS - variables to set when executing a TARGET's ACTIONS. */

Modified: branches/release/tools/build/v2/engine/timestamp.h
==============================================================================
--- branches/release/tools/build/v2/engine/timestamp.h Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/engine/timestamp.h 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -14,7 +14,6 @@
 #include "object.h"
 
 #ifdef OS_NT
-# define WIN32_LEAN_AND_MEAN
 # include <windows.h>
 #endif
 

Copied: branches/release/tools/build/v2/test/builtin_readlink.py (from r84524, trunk/tools/build/v2/test/builtin_readlink.py)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/tools/build/v2/test/builtin_readlink.py 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768, copy of r84524, trunk/tools/build/v2/test/builtin_readlink.py)
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+
+# Copyright 2012 Steven Watanabe
+# 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
+import os
+
+t = BoostBuild.Tester(pass_toolset=0)
+
+t.write("link-target", "")
+os.symlink("link-target", "link")
+
+t.write("file.jam", """
+ECHO [ READLINK link ] ;
+EXIT [ READLINK link-target ] : 0 ;
+""")
+
+t.run_build_system(["-ffile.jam"], stdout="""link-target
+
+""")
+
+t.cleanup()

Copied: branches/release/tools/build/v2/test/core_multifile_actions.py (from r86561, trunk/tools/build/v2/test/core_multifile_actions.py)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/tools/build/v2/test/core_multifile_actions.py 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768, copy of r86561, trunk/tools/build/v2/test/core_multifile_actions.py)
@@ -0,0 +1,202 @@
+#!/usr/bin/python
+
+# Copyright 2013 Steven Watanabe
+# 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 actions that produce multiple targets are handled
+# correctly. The rules are as follows:
+#
+# - If any action that updates a target is run, then the target
+# is considered to be out-of-date and all of its updating actions
+# are run in order.
+# - A target is considered updated when all of its updating actions
+# have completed successfully.
+# - If any updating action for a target fails, then the remaining
+# actions are skipped and the target is marked as failed.
+#
+# Note that this is a more thorough test case for the same
+# problem that core_parallel_multifile_actions_N.py checks for.
+
+import BoostBuild
+
+t = BoostBuild.Tester(pass_toolset=0, pass_d0=False)
+
+t.write("file.jam", """
+actions update
+{
+ echo updating $(<)
+}
+
+update x1 x2 ;
+update x2 x3 ;
+""")
+
+# Updating x1 should force x2 to update as well.
+t.run_build_system(["-ffile.jam", "x1"], stdout="""\
+...found 3 targets...
+...updating 3 targets...
+update x1
+updating x1 x2
+update x2
+updating x2 x3
+...updated 3 targets...
+""")
+
+# If x1 is up-to-date, we don't need to update x2,
+# even though x2 is missing.
+t.write("x1", "")
+t.run_build_system(["-ffile.jam", "x1"], stdout="""\
+...found 1 target...
+""")
+
+# Building x3 should update x1 and x2, even though
+# x1 would be considered up-to-date, taken alone.
+t.run_build_system(["-ffile.jam", "x3"], stdout="""\
+...found 3 targets...
+...updating 2 targets...
+update x1
+updating x1 x2
+update x2
+updating x2 x3
+...updated 3 targets...
+""")
+
+# Updating x2 should succeed, but x3 should be skipped
+t.rm("x1")
+t.write("file.jam", """\
+actions update
+{
+ echo updating $(<)
+}
+actions fail
+{
+ echo failed $(<)
+ exit 1
+}
+
+update x1 x2 ;
+fail x1 ;
+update x1 x3 ;
+update x2 ;
+update x3 ;
+""")
+
+t.run_build_system(["-ffile.jam", "x3"], status=1, stdout="""\
+...found 3 targets...
+...updating 3 targets...
+update x1
+updating x1 x2
+fail x1
+failed x1
+
+ echo failed x1
+ exit 1
+
+...failed fail x1...
+update x2
+updating x2
+...failed updating 2 targets...
+...updated 1 target...
+""")
+
+# Make sure that dependencies of targets that are
+# updated as a result of a multifile action are
+# processed correctly.
+t.rm("x1")
+t.write("file.jam", """\
+actions update
+{
+ echo updating $(<)
+}
+
+update x1 ;
+update x2 ;
+DEPENDS x2 : x1 ;
+update x2 x3 ;
+""")
+t.run_build_system(["-ffile.jam", "x3"], stdout="""\
+...found 3 targets...
+...updating 3 targets...
+update x1
+updating x1
+update x2
+updating x2
+update x2
+updating x2 x3
+...updated 3 targets...
+""")
+
+# JAM_SEMAPHORE rules:
+#
+# - if two updating actions have targets that share a semaphore,
+# these actions cannot be run in parallel.
+#
+t.write("file.jam", """\
+actions update
+{
+ echo updating $(<)
+}
+
+targets = x1 x2 ;
+JAM_SEMAPHORE on $(targets) = <s>update_sem ;
+update x1 x2 ;
+""")
+t.run_build_system(["-ffile.jam", "x1"], stdout="""\
+...found 2 targets...
+...updating 2 targets...
+update x1
+updating x1 x2
+...updated 2 targets...
+""")
+
+# A target can appear multiple times in an action
+t.write("file.jam", """\
+actions update
+{
+ echo updating $(<)
+}
+
+update x1 x1 ;
+""")
+t.run_build_system(["-ffile.jam", "x1"], stdout="""\
+...found 1 target...
+...updating 1 target...
+update x1
+updating x1 x1
+...updated 1 target...
+""")
+
+# Together actions should check that all the targets are the same
+# before combining.
+t.write("file.jam", """\
+actions together update
+{
+ echo updating $(<) : $(>)
+}
+
+update x1 x2 : s1 ;
+update x1 x2 : s2 ;
+
+update x3 : s3 ;
+update x3 x4 : s4 ;
+update x4 x3 : s5 ;
+DEPENDS all : x1 x2 x3 x4 ;
+""")
+t.run_build_system(["-ffile.jam"], stdout="""\
+...found 5 targets...
+...updating 4 targets...
+update x1
+updating x1 x2 : s1 s2
+update x3
+updating x3 : s3
+update x3
+updating x3 x4 : s4
+update x4
+updating x4 x3 : s5
+...updated 4 targets...
+""")
+
+
+
+t.cleanup()

Copied: branches/release/tools/build/v2/test/libjpeg.py (from r84665, trunk/tools/build/v2/test/libjpeg.py)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/tools/build/v2/test/libjpeg.py 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768, copy of r84665, trunk/tools/build/v2/test/libjpeg.py)
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+
+# Copyright (C) 2013 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
+import MockToolset
+
+t = BoostBuild.Tester(arguments=['toolset=mock', '--ignore-site-config', '--user-config='], pass_toolset=0)
+
+MockToolset.create(t)
+
+# Build from source
+t.write("libjpeg/jpeg.h", 'libjpeg')
+t.write("libjpeg/jpeg.c", 'jpeg')
+
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libjpeg : : <source>$(here)/libjpeg ;
+alias libjpeg : /libjpeg//libjpeg : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, '''
+source_file('jpeg.c', 'jpeg')
+action('-c -x c -I./libjpeg -o $jpeg.o $jpeg.c')
+action('--dll $jpeg.o -o $jpeg.so')
+action('--archive $jpeg.o -o $jpeg.a')
+''')
+
+t.run_build_system()
+t.expect_addition('bin/standalone/libjpeg/mock/debug/jpeg.dll')
+t.expect_addition('bin/standalone/libjpeg/mock/debug/link-static/jpeg.lib')
+
+t.rm('libjpeg')
+
+# Generic definitions that aren't configuration specific
+common_stuff = '''
+source_file('test.cpp', 'test.cpp')
+source_file('main.cpp', 'int main() {}')
+source_file('jpeg.h.cpp', '#include <jpeg.h>')
+action('-c -x c++ $main.cpp -o $main.o')
+'''
+t.write('test.cpp', 'test.cpp')
+
+# Default initialization - static library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libjpeg ;
+exe test : test.cpp /libjpeg//libjpeg : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o --static-lib=jpeg -o $config.exe')
+action('-c -x c++ $jpeg.h.cpp -o $jpeg.h.o')
+action('-c -x c++ $test.cpp -o $test.o')
+action('$test.o --static-lib=jpeg -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+# Default initialization - shared library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libjpeg ;
+exe test : test.cpp /libjpeg//libjpeg : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o --shared-lib=jpeg -o $config.exe')
+action('-c -x c++ $jpeg.h.cpp -o $jpeg.h.o')
+action('-c -x c++ $test.cpp -o $test.o')
+action('$test.o --shared-lib=jpeg -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+# Initialization in explicit location - static library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libjpeg : : <name>mylibjpeg <include>$(here)/libjpeg <search>$(here)/libjpeg ;
+exe test : test.cpp /libjpeg//libjpeg : : <link>static <link>shared ;
+""")
+
+t.write('libjpeg/jpeg.h', 'libjpeg')
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o -L./libjpeg --static-lib=mylibjpeg -o $config.exe')
+action('-c -x c++ $test.cpp -I./libjpeg -o $test.o')
+action('$test.o -L./libjpeg --static-lib=mylibjpeg -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+# Initialization in explicit location - shared library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libjpeg : : <name>mylibjpeg <include>$(here)/libjpeg <search>$(here)/libjpeg ;
+exe test : test.cpp /libjpeg//libjpeg : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o -L./libjpeg --shared-lib=mylibjpeg -o $config.exe')
+action('-c -x c++ $test.cpp -I./libjpeg -o $test.o')
+action('$test.o -L./libjpeg --shared-lib=mylibjpeg -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+t.cleanup()

Copied: branches/release/tools/build/v2/test/libpng.py (from r84498, trunk/tools/build/v2/test/libpng.py)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/tools/build/v2/test/libpng.py 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768, copy of r84498, trunk/tools/build/v2/test/libpng.py)
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+
+# Copyright (C) 2013 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
+import MockToolset
+
+t = BoostBuild.Tester(arguments=['toolset=mock', '--ignore-site-config', '--user-config='], pass_toolset=0)
+
+MockToolset.create(t)
+
+# Build from source
+t.write("libpng/png.h", 'libpng')
+t.write("libpng/png.c", 'png')
+
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libpng : : <source>$(here)/libpng ;
+alias libpng : /libpng//libpng : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, '''
+source_file('png.c', 'png')
+action('-c -x c -I./libpng -o $png.o $png.c')
+action('--dll $png.o -o $png.so')
+action('--archive $png.o -o $png.a')
+''')
+
+t.run_build_system()
+t.expect_addition('bin/standalone/libpng/mock/debug/png.dll')
+t.expect_addition('bin/standalone/libpng/mock/debug/link-static/png.lib')
+
+t.rm('libpng')
+
+# Generic definitions that aren't configuration specific
+common_stuff = '''
+source_file('test.cpp', 'test.cpp')
+source_file('main.cpp', 'int main() {}')
+source_file('png.h.cpp', '#include <png.h>')
+action('-c -x c++ $main.cpp -o $main.o')
+'''
+t.write('test.cpp', 'test.cpp')
+
+# Default initialization - static library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libpng ;
+exe test : test.cpp /libpng//libpng : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o --static-lib=png -o $config.exe')
+action('-c -x c++ $png.h.cpp -o $png.h.o')
+action('-c -x c++ $test.cpp -o $test.o')
+action('$test.o --static-lib=png -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+# Default initialization - shared library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libpng ;
+exe test : test.cpp /libpng//libpng : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o --shared-lib=png -o $config.exe')
+action('-c -x c++ $png.h.cpp -o $png.h.o')
+action('-c -x c++ $test.cpp -o $test.o')
+action('$test.o --shared-lib=png -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+# Initialization in explicit location - static library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libpng : : <name>mylibpng <include>$(here)/libpng <search>$(here)/libpng ;
+exe test : test.cpp /libpng//libpng : : <link>static <link>shared ;
+""")
+
+t.write('libpng/png.h', 'libpng')
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o -L./libpng --static-lib=mylibpng -o $config.exe')
+action('-c -x c++ $test.cpp -I./libpng -o $test.o')
+action('$test.o -L./libpng --static-lib=mylibpng -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+# Initialization in explicit location - shared library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libpng : : <name>mylibpng <include>$(here)/libpng <search>$(here)/libpng ;
+exe test : test.cpp /libpng//libpng : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o -L./libpng --shared-lib=mylibpng -o $config.exe')
+action('-c -x c++ $test.cpp -I./libpng -o $test.o')
+action('$test.o -L./libpng --shared-lib=mylibpng -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+t.cleanup()

Copied: branches/release/tools/build/v2/test/libtiff.py (from r84665, trunk/tools/build/v2/test/libtiff.py)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/tools/build/v2/test/libtiff.py 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768, copy of r84665, trunk/tools/build/v2/test/libtiff.py)
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+
+# Copyright (C) 2013 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
+import MockToolset
+
+t = BoostBuild.Tester(arguments=['toolset=mock', '--ignore-site-config', '--user-config='], pass_toolset=0)
+
+MockToolset.create(t)
+
+# Build from source
+t.write("libtiff/tiff.h", 'libtiff')
+t.write("libtiff/tiff.c", 'tiff')
+
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libtiff : : <source>$(here)/libtiff ;
+alias libtiff : /libtiff//libtiff : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, '''
+source_file('tiff.c', 'tiff')
+action('-c -x c -I./libtiff -o $tiff.o $tiff.c')
+action('--dll $tiff.o -o $tiff.so')
+action('--archive $tiff.o -o $tiff.a')
+''')
+
+t.run_build_system()
+t.expect_addition('bin/standalone/libtiff/mock/debug/tiff.dll')
+t.expect_addition('bin/standalone/libtiff/mock/debug/link-static/tiff.lib')
+
+t.rm('libtiff')
+
+# Generic definitions that aren't configuration specific
+common_stuff = '''
+source_file('test.cpp', 'test.cpp')
+source_file('main.cpp', 'int main() {}')
+source_file('tiff.h.cpp', '#include <tiff.h>')
+action('-c -x c++ $main.cpp -o $main.o')
+'''
+t.write('test.cpp', 'test.cpp')
+
+# Default initialization - static library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libtiff ;
+exe test : test.cpp /libtiff//libtiff : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o --static-lib=tiff -o $config.exe')
+action('-c -x c++ $tiff.h.cpp -o $tiff.h.o')
+action('-c -x c++ $test.cpp -o $test.o')
+action('$test.o --static-lib=tiff -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+# Default initialization - shared library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libtiff ;
+exe test : test.cpp /libtiff//libtiff : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o --shared-lib=tiff -o $config.exe')
+action('-c -x c++ $tiff.h.cpp -o $tiff.h.o')
+action('-c -x c++ $test.cpp -o $test.o')
+action('$test.o --shared-lib=tiff -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+# Initialization in explicit location - static library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libtiff : : <name>mylibtiff <include>$(here)/libtiff <search>$(here)/libtiff ;
+exe test : test.cpp /libtiff//libtiff : : <link>static <link>shared ;
+""")
+
+t.write('libtiff/tiff.h', 'libtiff')
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o -L./libtiff --static-lib=mylibtiff -o $config.exe')
+action('-c -x c++ $test.cpp -I./libtiff -o $test.o')
+action('$test.o -L./libtiff --static-lib=mylibtiff -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+# Initialization in explicit location - shared library
+t.rm('bin')
+t.write("Jamroot.jam", """
+path-constant here : . ;
+using libtiff : : <name>mylibtiff <include>$(here)/libtiff <search>$(here)/libtiff ;
+exe test : test.cpp /libtiff//libtiff : : <link>static <link>shared ;
+""")
+
+MockToolset.set_expected(t, common_stuff + '''
+action('$main.o -L./libtiff --shared-lib=mylibtiff -o $config.exe')
+action('-c -x c++ $test.cpp -I./libtiff -o $test.o')
+action('$test.o -L./libtiff --shared-lib=mylibtiff -o $test')
+''')
+t.run_build_system()
+t.expect_addition('bin/mock/debug/test.exe')
+t.expect_addition('bin/mock/debug/link-static/test.exe')
+
+t.cleanup()

Copied: branches/release/tools/build/v2/test/link.py (from r86709, trunk/tools/build/v2/test/link.py)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/tools/build/v2/test/link.py 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768, copy of r86709, trunk/tools/build/v2/test/link.py)
@@ -0,0 +1,154 @@
+#!/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)
+
+# Tests the link-directory rule used to create the
+# common boost/ directory in the new git layout.
+
+import BoostBuild
+
+def ignore_config(t):
+ """These files are created by the configuration logic in link.jam
+ They may or may not exist, depending on the system."""
+ t.ignore("bin/test-hardlink")
+ t.ignore("bin/test-hardlink-source")
+ t.ignore("bin/test-symlink")
+ t.ignore("bin/test-symlink-source")
+
+def test_basic():
+ """Test creation of a single link"""
+ t = BoostBuild.Tester()
+ t.write("jamroot.jam", """\
+ import link ;
+ link-directory dir1-link : src/dir1/include : <location>. ;
+ """)
+
+ t.write("src/dir1/include/file1.h", "file1")
+
+ t.run_build_system()
+
+ t.expect_addition("include/file1.h")
+ t.expect_content("include/file1.h", "file1")
+ ignore_config(t)
+ t.expect_nothing_more()
+ t.cleanup()
+
+def test_merge_two():
+ """Test merging two directories"""
+ t = BoostBuild.Tester()
+ t.write("jamroot.jam", """\
+ import link ;
+ link-directory dir1-link : src/dir1/include : <location>. ;
+ link-directory dir2-link : src/dir2/include : <location>. ;
+ """)
+
+ t.write("src/dir1/include/file1.h", "file1")
+ t.write("src/dir2/include/file2.h", "file2")
+
+ t.run_build_system()
+
+ t.expect_addition("include/file1.h")
+ t.expect_content("include/file1.h", "file1")
+ t.expect_addition("include/file2.h")
+ t.expect_content("include/file2.h", "file2")
+ ignore_config(t)
+ t.expect_nothing_more()
+ t.cleanup()
+
+def test_merge_existing():
+ """Test adding a link when a different symlink already exists"""
+ t = BoostBuild.Tester()
+ t.write("jamroot.jam", """\
+ import link ;
+ link-directory dir1-link : src/dir1/include : <location>. ;
+ link-directory dir2-link : src/dir2/include : <location>. ;
+ """)
+
+ t.write("src/dir1/include/file1.h", "file1")
+ t.write("src/dir2/include/file2.h", "file2")
+
+ t.run_build_system(["dir1-link"])
+
+ t.expect_addition("include/file1.h")
+ t.expect_content("include/file1.h", "file1")
+ ignore_config(t)
+ t.expect_nothing_more()
+
+ t.run_build_system(["dir2-link"])
+
+ t.expect_addition("include/file2.h")
+ t.expect_content("include/file2.h", "file2")
+ # If include is a symlink to src/dir1/include, then
+ # we have to delete it and add a directory.
+ t.ignore_removal("include/file1.h")
+ ignore_config(t)
+ t.expect_nothing_more()
+
+ t.cleanup()
+
+def test_merge_recursive():
+ "Test merging several directories including common prefixes"
+ t = BoostBuild.Tester()
+ t.write("jamroot.jam", """\
+ import link ;
+ link-directory dir1-link : src/dir1/include : <location>. ;
+ link-directory dir2-link : src/dir2/include : <location>. ;
+ link-directory dir3-link : src/dir3/include : <location>. ;
+ """)
+
+ t.write("src/dir1/include/file1.h", "file1")
+ t.write("src/dir2/include/file2.h", "file2")
+ t.write("src/dir2/include/nested/file3.h", "file3")
+ t.write("src/dir3/include/nested/file4.h", "file4")
+
+ t.run_build_system()
+
+ t.expect_addition("include/file1.h")
+ t.expect_content("include/file1.h", "file1")
+ t.expect_addition("include/file2.h")
+ t.expect_content("include/file2.h", "file2")
+ t.expect_addition("include/nested/file3.h")
+ t.expect_content("include/nested/file3.h", "file3")
+ t.expect_addition("include/nested/file4.h")
+ t.expect_content("include/nested/file4.h", "file4")
+ ignore_config(t)
+ t.expect_nothing_more()
+
+ t.cleanup()
+
+def test_include_scan():
+ """Make sure that the #include scanner finds the headers"""
+ t = BoostBuild.Tester()
+ t.write("jamroot.jam", """\
+ import link ;
+ link-directory dir1-link : src/dir1/include : <location>. ;
+ link-directory dir2-link : src/dir2/include : <location>. ;
+ obj test : test.cpp :
+ <include>include
+ <implicit-dependency>dir1-link
+ <implicit-dependency>dir2-link ;
+ """)
+
+ t.write("src/dir1/include/file1.h", "#include <file2.h>\n")
+ t.write("src/dir2/include/file2.h", "int f();\n")
+ t.write("test.cpp", """\
+ #include <file1.h>
+ int main() { f(); }
+ """);
+
+ t.run_build_system(["test"])
+
+ t.expect_addition("bin/$toolset/debug/test.obj")
+
+ t.run_build_system()
+ t.expect_nothing_more()
+
+ t.cleanup()
+
+test_basic()
+test_merge_two()
+test_merge_existing()
+test_merge_recursive()
+test_include_scan()

Modified: branches/release/tools/build/v2/test/qt5/jamroot.jam
==============================================================================
--- branches/release/tools/build/v2/test/qt5/jamroot.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/test/qt5/jamroot.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -44,7 +44,7 @@
       [ link qtdeclarative.cpp /qt5//QtDeclarative ]
 
       # QtQuick version2
- [ run qtquick.cpp /qt5//QtQuick : : $(CWD)/qtquick.qml ]
+ [ run qtquick.cpp /qt5//QtQuick : -platform offscreen : $(CWD)/qtquick.qml ]
 
       # Help systems.
       [ link qthelp.cpp /qt5//QtHelp ]

Copied: branches/release/tools/build/v2/test/source_order.py (from r86767, trunk/tools/build/v2/test/source_order.py)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/tools/build/v2/test/source_order.py 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768, copy of r86767, trunk/tools/build/v2/test/source_order.py)
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+
+# Copyright 2013 Steven Watanabe
+# 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 action sources are not reordered
+
+import BoostBuild
+
+t = BoostBuild.Tester()
+
+t.write("check-order.jam", """\
+import type ;
+import generators ;
+
+type.register ORDER_TEST : order-test ;
+
+SPACE = " " ;
+nl = "\n" ;
+actions check-order
+{
+ echo$(SPACE)$(>[1])$(SPACE)>$(<[1])
+ echo$(SPACE)$(>[2-])$(SPACE)>>$(<[1])$(nl)
+}
+
+generators.register-composing check-order.check-order : C : ORDER_TEST ;
+""")
+
+# The aliases are necessary for this test, since
+# the targets were sorted by virtual target
+# id, not by file name.
+t.write("jamroot.jam", """\
+import check-order ;
+alias file1 : file1.c ;
+alias file2 : file2.c ;
+alias file3 : file3.c ;
+order-test check : file2 file1 file3 ;
+""")
+
+t.write("file1.c", "")
+t.write("file2.c", "")
+t.write("file3.c", "")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/check.order-test")
+t.expect_content("bin/$toolset/debug/check.order-test", """\
+file2.c
+file1.c
+file3.c
+""", True)
+
+t.cleanup()

Modified: branches/release/tools/build/v2/test/test_all.py
==============================================================================
--- branches/release/tools/build/v2/test/test_all.py Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/test/test_all.py 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -182,6 +182,7 @@
          "core_actions_quietly",
          "core_at_file",
          "core_bindrule",
+ "core_multifile_actions",
          "core_nt_cmd_line",
          "core_option_d2",
          "core_option_l",
@@ -220,6 +221,7 @@
          "lib_source_property",
          "library_chain",
          "library_property",
+ "link",
          "load_order",
          "loop",
          "make_rule",
@@ -251,6 +253,7 @@
          "skipping",
          "sort_rule",
          "source_locations",
+ "source_order",
          "space_in_path",
          "stage",
          "standalone",

Modified: branches/release/tools/build/v2/tools/boostbook.jam
==============================================================================
--- branches/release/tools/build/v2/tools/boostbook.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/tools/boostbook.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -178,6 +178,7 @@
 
 rule make-error ( message * )
 {
+ import errors ;
     return [ errors.nearest-user-location ] $(message) ;
 }
 
@@ -204,7 +205,6 @@
     {
         if ! [ path.glob $(.docbook-xsl-dir) : common/common.xsl ]
         {
- import errors ;
             .error-message = [ make-error BoostBook: could not find docbook XSL stylesheets
                 in: [ path.native $(.docbook-xsl-dir) ] ] ;
         }
@@ -223,7 +223,6 @@
     {
         if ! [ path.glob $(.docbook-dtd-dir) : docbookx.dtd ]
         {
- import errors ;
             .error-message = [ make-error BoostBook: could not find docbook DTD in: [
                 path.native $(.docbook-dtd-dir) ] ] ;
         }
@@ -278,7 +277,6 @@
 {
     if $(boostbook-dir) && ! [ path.glob $(boostbook-dir) : xsl ]
     {
- import errors ;
         .error-message = [ make-error BoostBook: could not find boostbook in: [ path.native
             $(boostbook-dir) ] ] ;
     }

Deleted: branches/release/tools/build/v2/tools/jpeg.jam
==============================================================================
--- branches/release/tools/build/v2/tools/jpeg.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86767)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,233 +0,0 @@
-# Copyright (c) 2010 Vladimir Prus.
-# Copyright (c) 2013 Steven Watanabe
-#
-# 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)
-
-# Supports the libjpeg library
-#
-# After 'using libjpeg', the following targets are available:
-#
-# /libjpeg//libjpeg -- The libjpeg library
-
-import project ;
-import ac ;
-import errors ;
-import "class" : new ;
-import targets ;
-import path ;
-import modules ;
-import errors ;
-import indirect ;
-import property ;
-import property-set ;
-
-header = jconfig.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h jpeglib.h
- jversion.h ;
-
-names = libjpeg ;
-
-sources = jaricom.c jcapimin.c jcapistd.c jcarith.c jccoefct.c jccolor.c
- jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c
- jcomapi.c jcparam.c jcprepct.c jcsample.c jctrans.c jdapimin.c
- jdapistd.c jdarith.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c
- jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c
- jdmerge.c jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c
- jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jquant1.c ;
-
-library-id = 0 ;
-
-if --debug-configuration in [ modules.peek : ARGV ]
-{
- .debug = true ;
-}
-
-# Initializes the libjpeg library.
-#
-# libjpeg can be configured either to use pre-existing binaries
-# or to build the library from source.
-#
-# Options for configuring a prebuilt libjpeg::
-#
-# <search>
-# The directory containing the libjpeg binaries.
-# <name>
-# Overrides the default library name.
-# <include>
-# The directory containing the libjpeg headers.
-#
-# If none of these options is specified, then the environmental
-# variables LIBJPEG_LIBRARY_PATH, LIBJPEG_NAME, and LIBJPEG_INCLUDE will
-# be used instead.
-#
-# Options for building libjpeg from source::
-#
-# <source>
-# The libjpeg source directory. Defaults to the environmental variable
-# LIBJPEG_SOURCE.
-# <tag>
-# A rule which computes the actual name of the compiled
-# libraries based on the build properties. Ignored
-# when using precompiled binaries.
-# <build-name>
-# The base name to use for the compiled library. Ignored
-# when using precompiled binaries.
-#
-# Examples::
-#
-# # Find libjpeg in the default system location
-# using libjpeg ;
-# # Build libjpeg from source
-# using libjpeg : 8c : <source>/home/steven/libjpeg-8c ;
-# # Find libjpeg in /usr/local
-# using libjpeg : 8c
-# : <include>/usr/local/include <search>/usr/local/lib ;
-# # Build libjpeg from source for msvc and find
-# # prebuilt binaries for gcc.
-# using libjpeg : 8c : <source>C:/Devel/src/libjpeg-8c : <toolset>msvc ;
-# using libjpeg : 8c : : <toolset>gcc ;
-#
-rule init (
- version ?
- # The libjpeg version (currently ignored)
-
- : options *
- # A list of the options to use
-
- : requirements *
- # The requirements for the libjpeg target
-
- : is-default ?
- # Default configurations are only used when libjpeg
- # has not yet been configured.
- )
-{
- local caller = [ project.current ] ;
-
- if ! $(.initialized)
- {
- .initialized = true ;
-
- project.initialize $(__name__) ;
- .project = [ project.current ] ;
- project libjpeg ;
- }
-
- local library-path = [ property.select <search> : $(options) ] ;
- library-path = $(library-path:G=) ;
- local include-path = [ property.select <include> : $(options) ] ;
- include-path = $(include-path:G=) ;
- local source-path = [ property.select <source> : $(options) ] ;
- source-path = $(source-path:G=) ;
- local library-name = [ property.select <name> : $(options) ] ;
- library-name = $(library-name:G=) ;
- local tag = [ property.select <tag> : $(options) ] ;
- tag = $(tag:G=) ;
- local build-name = [ property.select <build-name> : $(options) ] ;
- build-name = $(build-name:G=) ;
-
- condition = [ property-set.create $(requirements) ] ;
- condition = [ property-set.create [ $(condition).base ] ] ;
-
- local no-build-from-source ;
- # Ignore environmental ZLIB_SOURCE if this initialization
- # requested to search for a specific pre-built library.
- if $(library-path) || $(include-path) || $(library-name)
- {
- if $(source-path) || $(tag) || $(build-name)
- {
- errors.user-error "incompatible options for libjpeg:"
- [ property.select <search> <include> <name> : $(options) ] "and"
- [ property.select <source> <tag> <build-name> : $(options) ] ;
- }
- else
- {
- no-build-from-source = true ;
- }
- }
-
- source-path ?= [ modules.peek : ZLIB_SOURCE ] ;
-
- if $(.configured.$(condition))
- {
- if $(is-default)
- {
- if $(.debug)
- {
- ECHO "notice: [libjpeg] libjpeg is already configured" ;
- }
- }
- else
- {
- errors.user-error "libjpeg is already configured" ;
- }
- return ;
- }
- else if $(source-path) && ! $(no-build-from-source)
- {
- build-name ?= z ;
- library-id = [ CALC $(library-id) + 1 ] ;
- tag = [ MATCH ^@?(.*)$ : $(tag) ] ;
- if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ]
- {
- tag = [ indirect.make $(tag) : [ $(caller).project-module ] ] ;
- }
- sources = [ path.glob $(source-path) : $(sources) ] ;
- if $(.debug)
- {
- ECHO "notice: [libjpeg] Building libjpeg from source as $(build-name)" ;
- if $(condition)
- {
- ECHO "notice: [libjpeg] Condition" [ $(condition).raw ] ;
- }
- if $(sources)
- {
- ECHO "notice: [libjpeg] found libjpeg source in $(source-path)" ;
- }
- else
- {
- ECHO "warning: [libjpeg] could not find libjpeg source in $(source-path)" ;
- }
- }
- local target ;
- if $(sources) {
- target = [ targets.create-typed-target LIB : $(.project)
- : $(build-name).$(library-id)
- : $(sources)
- : $(requirements)
- <tag>@$(tag)
- <include>$(source-path)
- <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
- <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
- <link>shared:<define>ZLIB_DLL
- :
- : <include>$(source-path) ] ;
- }
-
- local mt = [ new ac-library libjpeg : $(.project) : $(condition) ] ;
- $(mt).set-header $(header) ;
- $(mt).set-default-names $(names) ;
- if $(target)
- {
- $(mt).set-target $(target) ;
- }
- targets.main-target-alternative $(mt) ;
- } else {
- if $(.debug)
- {
- ECHO "notice: [libjpeg] Using pre-installed library" ;
- if $(condition)
- {
- ECHO "notice: [libjpeg] Condition" [ $(condition).raw ] ;
- }
- }
-
- local mt = [ new ac-library libjpeg : $(.project) : $(condition) :
- $(include-path) : $(library-path) : $(library-name) : $(root) ] ;
- $(mt).set-header $(header) ;
- $(mt).set-default-names $(names) ;
- targets.main-target-alternative $(mt) ;
- }
- .configured.$(condition) = true ;
-}

Copied and modified: branches/release/tools/build/v2/tools/libjpeg.jam (from r84473, trunk/tools/build/v2/tools/libjpeg.jam)
==============================================================================
--- trunk/tools/build/v2/tools/libjpeg.jam Fri May 24 23:51:14 2013 (r84473, copy source)
+++ branches/release/tools/build/v2/tools/libjpeg.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -23,10 +23,9 @@
 import property ;
 import property-set ;
 
-header = jconfig.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h jpeglib.h
- jversion.h ;
+header = jpeglib.h ;
 
-names = libjpeg ;
+names = jpeg ;
 
 sources = jaricom.c jcapimin.c jcapistd.c jcarith.c jccoefct.c jccolor.c
         jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c
@@ -166,7 +165,7 @@
     }
     else if $(source-path) && ! $(no-build-from-source)
     {
- build-name ?= z ;
+ build-name ?= jpeg ;
         library-id = [ CALC $(library-id) + 1 ] ;
         tag = [ MATCH ^@?(.*)$ : $(tag) ] ;
         if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ]

Copied and modified: branches/release/tools/build/v2/tools/libpng.jam (from r84473, trunk/tools/build/v2/tools/libpng.jam)
==============================================================================
--- trunk/tools/build/v2/tools/libpng.jam Fri May 24 23:51:14 2013 (r84473, copy source)
+++ branches/release/tools/build/v2/tools/libpng.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -24,7 +24,7 @@
 import property-set ;
 
 header = png.h ;
-names = libpng ;
+names = png ;
 
 sources = png.c pngerror.c pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c pngrutil.c
             pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c ;
@@ -124,7 +124,7 @@
     condition = [ property-set.create [ $(condition).base ] ] ;
 
     local no-build-from-source ;
- # Ignore environmental ZLIB_SOURCE if this initialization
+ # Ignore environmental LIBPNG_SOURCE if this initialization
     # requested to search for a specific pre-built library.
     if $(library-path) || $(include-path) || $(library-name)
     {
@@ -140,7 +140,7 @@
         }
     }
 
- source-path ?= [ modules.peek : ZLIB_SOURCE ] ;
+ source-path ?= [ modules.peek : LIBPNG_SOURCE ] ;
 
     if $(.configured.$(condition))
     {
@@ -159,7 +159,7 @@
     }
     else if $(source-path) && ! $(no-build-from-source)
     {
- build-name ?= z ;
+ build-name ?= png ;
         library-id = [ CALC $(library-id) + 1 ] ;
         tag = [ MATCH ^@?(.*)$ : $(tag) ] ;
         if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ]
@@ -193,7 +193,7 @@
                 <include>$(source-path)
                 <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
                 <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
- <link>shared:<define>ZLIB_DLL
+ <link>shared:<define>LIBPNG_DLL
               :
               : <include>$(source-path) ] ;
         }

Copied and modified: branches/release/tools/build/v2/tools/libtiff.jam (from r84473, trunk/tools/build/v2/tools/libtiff.jam)
==============================================================================
--- trunk/tools/build/v2/tools/libtiff.jam Fri May 24 23:51:14 2013 (r84473, copy source)
+++ branches/release/tools/build/v2/tools/libtiff.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -23,9 +23,8 @@
 import property ;
 import property-set ;
 
-header = tiff.h tiffio.hxx ;
-
-names = libtiff ;
+header = tiff.h ;
+names = tiff ;
 
 sources = tif_aux.c tif_close.c tif_codec.c tif_color.c tif_compress.c tif_dir.c tif_dirinfo.c
         tif_dirread.c tif_dirwrite.c tif_dumpmode.c tif_error.c tif_extension.c tif_fax3.c tif_fax3sm.c
@@ -163,7 +162,7 @@
     }
     else if $(source-path) && ! $(no-build-from-source)
     {
- build-name ?= z ;
+ build-name ?= tiff ;
         library-id = [ CALC $(library-id) + 1 ] ;
         tag = [ MATCH ^@?(.*)$ : $(tag) ] ;
         if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ]

Copied and modified: branches/release/tools/build/v2/tools/link.jam (from r84524, trunk/tools/build/v2/tools/link.jam)
==============================================================================
--- trunk/tools/build/v2/tools/link.jam Sun May 26 20:02:43 2013 (r84524, copy source)
+++ branches/release/tools/build/v2/tools/link.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -10,6 +10,7 @@
 import configure ;
 import path ;
 import property ;
+import property-set ;
 import common ;
 
 rule get-root-project ( project )
@@ -33,7 +34,7 @@
    $(TOUCH) "$(<)"
 }
 
-rule can-symlink ( project )
+rule can-symlink ( project : ps )
 {
     if ! $(.can-symlink)
     {
@@ -44,7 +45,7 @@
         local target = [ new file-target test-symlink : :
             $(project) : [ new action $(source-target) : link.mklink ] ] ;
 
- if [ configure.try-build $(target) : "symlinks supported" ]
+ if [ configure.try-build $(target) : $(ps) : "symlinks supported" ]
         {
             .can-symlink = true ;
         }
@@ -60,11 +61,10 @@
 }
 
 
-rule can-hardlink ( project )
+rule can-hardlink ( project : ps )
 {
     if ! $(.can-hardlink)
     {
- # Find the root project.
         local root-project = [ get-root-project $(project) ] ;
 
         local source-target = [ new file-target test-hardlink-source : :
@@ -72,7 +72,7 @@
         local target = [ new file-target test-hardlink : :
             $(project) : [ new action $(source-target) : link.hardlink ] ] ;
 
- if [ configure.try-build $(target) : "hardlinks supported" ]
+ if [ configure.try-build $(target) : $(ps) : "hardlinks supported" ]
         {
             .can-hardlink = true ;
         }
@@ -143,10 +143,8 @@
         local files = [ path.glob-tree $(location) : * ] ;
         local targets ;
 
- if ! [ link.can-symlink $(self.project) ]
- {
- link.can-hardlink $(self.project) ;
- }
+ link.can-symlink $(self.project) : $(property-set) ;
+ link.can-hardlink $(self.project) : $(property-set) ;
 
         if [ $(property-set).get <location> ]
         {
@@ -183,15 +181,15 @@
     local source = [ path.native [ path.relative-to [ path.pwd ] $(>) ] ] ;
     LOCATE on $(target) = . ;
     DEPENDS $(.current-target) : $(target) ;
- if $(.can-symlink) = true
- {
- link.mklink $(target) : $(source) ;
- }
- else if $(.can-hardlink) = true
+ if $(.can-hardlink) = true
     {
         DEPENDS $(target) : $(source) ;
         link.hardlink $(target) : $(source) ;
     }
+ else if $(.can-symlink) = true
+ {
+ link.mklink $(target) : $(source) ;
+ }
     else
     {
         DEPENDS $(target) : $(source) ;
@@ -229,10 +227,6 @@
         DEPENDS $(.current-target) : $(target) ;
         common.mkdir $(target) ;
     }
- if ! [ on $(target) return $(RM) ]
- {
- NOUPDATE $(target) ;
- }
     MKLINK_OR_DIR on $(target) = mkdir \"$(target)\" ;
 }
 
@@ -244,6 +238,11 @@
     link.rm $(target) ;
 }
 
+rule mklink-or-dir
+{
+ NOUPDATE $(<) ;
+}
+
 actions mklink-or-dir
 {
     $(MKLINK_OR_DIR)
@@ -260,6 +259,7 @@
             local s = [ path.native [ path.relative-to [ path.pwd ] $(target) ] ] ;
             LOCATE on $(t) = . ;
             DEPENDS $(t) : $(s) ;
+ NOUPDATE $(s) ;
         }
         if $(split)
         {

Modified: branches/release/tools/build/v2/tools/mpi.jam
==============================================================================
--- branches/release/tools/build/v2/tools/mpi.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/tools/mpi.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -314,7 +314,7 @@
    
       # Prepend COMPILER as the executable name, to match the format of
       # other compilation commands.
- compile_flags = "COMPILER $(compile_flags)" ;
+ compile_flags = "COMPILER $(compile_flags) -DOMPI_SKIP_MPICXX " ;
       link_flags = "COMPILER $(link_flags)" ;
     }
     # Look for LAM-MPI's -showme

Modified: branches/release/tools/build/v2/tools/msvc.jam
==============================================================================
--- branches/release/tools/build/v2/tools/msvc.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/tools/msvc.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -55,7 +55,7 @@
 # using msvc : 6.5 : cl.exe ;
 # using msvc : 7.0 : Y:/foo/bar/cl.exe ;
 #
-# The version parameter may be ommited:
+# The version parameter may be omitted:
 #
 # using msvc : : Z:/foo/bar/cl.exe ;
 #
@@ -901,9 +901,9 @@
 
                 setup-$(c) = [ feature.get-values <setup-$(c)> : $(options) ] ;
 
- if ! $(setup-$(c))-is-not-empty
+ if ! $(setup-$(c))-is-defined
                 {
- if $(global-setup)-is-not-empty
+ if $(global-setup)-is-defined
                     {
                         setup-$(c) = $(global-setup) ;
 
@@ -916,7 +916,8 @@
                     }
                     else
                     {
- setup-$(c) = [ locate-default-setup $(command) : $(parent) : $(default-setup-$(c)) ] ;
+ setup-$(c) = [ locate-default-setup $(command) :
+ $(parent) : $(default-setup-$(c)) ] ;
                     }
                 }
 
@@ -1381,7 +1382,8 @@
                      merom-xe kentsfield kentsfield-xe penryn wolfdale
                      yorksfield nehalem sandy-bridge ivy-bridge haswell ;
 .cpu-type-amd64 = k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3
- athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3 btver1 btver2 ;
+ athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3
+ btver1 btver2 ;
 .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 ;

Modified: branches/release/tools/build/v2/tools/msvc.py
==============================================================================
--- branches/release/tools/build/v2/tools/msvc.py Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/tools/msvc.py 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -71,7 +71,7 @@
 # using msvc : 6.5 : cl.exe ;
 # using msvc : 7.0 : Y:/foo/bar/cl.exe ;
 #
-# The version parameter may be ommited:
+# The version parameter may be omitted:
 #
 # using msvc : : Z:/foo/bar/cl.exe ;
 #

Deleted: branches/release/tools/build/v2/tools/png.jam
==============================================================================
--- branches/release/tools/build/v2/tools/png.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86767)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,226 +0,0 @@
-# Copyright (c) 2010 Vladimir Prus.
-# Copyright (c) 2013 Steven Watanabe
-#
-# 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)
-
-# Supports the libpng library
-#
-# After 'using libpng', the following targets are available:
-#
-# /libpng//libpng -- The libpng library
-
-import project ;
-import ac ;
-import errors ;
-import "class" : new ;
-import targets ;
-import path ;
-import modules ;
-import errors ;
-import indirect ;
-import property ;
-import property-set ;
-
-header = png.h ;
-names = libpng ;
-
-sources = png.c pngerror.c pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c pngrutil.c
- pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c ;
-
-library-id = 0 ;
-
-if --debug-configuration in [ modules.peek : ARGV ]
-{
- .debug = true ;
-}
-
-# Initializes the libpng library.
-#
-# libpng can be configured either to use pre-existing binaries
-# or to build the library from source.
-#
-# Options for configuring a prebuilt libpng::
-#
-# <search>
-# The directory containing the libpng binaries.
-# <name>
-# Overrides the default library name.
-# <include>
-# The directory containing the libpng headers.
-#
-# If none of these options is specified, then the environmental
-# variables LIBPNG_LIBRARY_PATH, LIBPNG_NAME, and LIBPNG_INCLUDE will
-# be used instead.
-#
-# Options for building libpng from source::
-#
-# <source>
-# The libpng source directory. Defaults to the environmental variable
-# LIBPNG_SOURCE.
-# <tag>
-# A rule which computes the actual name of the compiled
-# libraries based on the build properties. Ignored
-# when using precompiled binaries.
-# <build-name>
-# The base name to use for the compiled library. Ignored
-# when using precompiled binaries.
-#
-# Examples::
-#
-# # Find libpng in the default system location
-# using libpng ;
-# # Build libpng from source
-# using libpng : 1.5.4 : <source>/home/steven/libpng-1.5.4 ;
-# # Find libpng in /usr/local
-# using libpng : 1.5.4
-# : <include>/usr/local/include <search>/usr/local/lib ;
-# # Build libpng from source for msvc and find
-# # prebuilt binaries for gcc.
-# using libpng : 1.5.4 : <source>C:/Devel/src/libpng-1.5.4 : <toolset>msvc ;
-# using libpng : 1.5.4 : : <toolset>gcc ;
-#
-rule init (
- version ?
- # The libpng version (currently ignored)
-
- : options *
- # A list of the options to use
-
- : requirements *
- # The requirements for the libpng target
-
- : is-default ?
- # Default configurations are only used when libpng
- # has not yet been configured.
- )
-{
- local caller = [ project.current ] ;
-
- if ! $(.initialized)
- {
- .initialized = true ;
-
- project.initialize $(__name__) ;
- .project = [ project.current ] ;
- project libpng ;
- }
-
- local library-path = [ property.select <search> : $(options) ] ;
- library-path = $(library-path:G=) ;
- local include-path = [ property.select <include> : $(options) ] ;
- include-path = $(include-path:G=) ;
- local source-path = [ property.select <source> : $(options) ] ;
- source-path = $(source-path:G=) ;
- local library-name = [ property.select <name> : $(options) ] ;
- library-name = $(library-name:G=) ;
- local tag = [ property.select <tag> : $(options) ] ;
- tag = $(tag:G=) ;
- local build-name = [ property.select <build-name> : $(options) ] ;
- build-name = $(build-name:G=) ;
-
- condition = [ property-set.create $(requirements) ] ;
- condition = [ property-set.create [ $(condition).base ] ] ;
-
- local no-build-from-source ;
- # Ignore environmental ZLIB_SOURCE if this initialization
- # requested to search for a specific pre-built library.
- if $(library-path) || $(include-path) || $(library-name)
- {
- if $(source-path) || $(tag) || $(build-name)
- {
- errors.user-error "incompatible options for libpng:"
- [ property.select <search> <include> <name> : $(options) ] "and"
- [ property.select <source> <tag> <build-name> : $(options) ] ;
- }
- else
- {
- no-build-from-source = true ;
- }
- }
-
- source-path ?= [ modules.peek : ZLIB_SOURCE ] ;
-
- if $(.configured.$(condition))
- {
- if $(is-default)
- {
- if $(.debug)
- {
- ECHO "notice: [libpng] libpng is already configured" ;
- }
- }
- else
- {
- errors.user-error "libpng is already configured" ;
- }
- return ;
- }
- else if $(source-path) && ! $(no-build-from-source)
- {
- build-name ?= z ;
- library-id = [ CALC $(library-id) + 1 ] ;
- tag = [ MATCH ^@?(.*)$ : $(tag) ] ;
- if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ]
- {
- tag = [ indirect.make $(tag) : [ $(caller).project-module ] ] ;
- }
- sources = [ path.glob $(source-path) : $(sources) ] ;
- if $(.debug)
- {
- ECHO "notice: [libpng] Building libpng from source as $(build-name)" ;
- if $(condition)
- {
- ECHO "notice: [libpng] Condition" [ $(condition).raw ] ;
- }
- if $(sources)
- {
- ECHO "notice: [libpng] found libpng source in $(source-path)" ;
- }
- else
- {
- ECHO "warning: [libpng] could not find libpng source in $(source-path)" ;
- }
- }
- local target ;
- if $(sources) {
- target = [ targets.create-typed-target LIB : $(.project)
- : $(build-name).$(library-id)
- : $(sources)
- : $(requirements)
- <tag>@$(tag)
- <include>$(source-path)
- <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
- <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
- <link>shared:<define>ZLIB_DLL
- :
- : <include>$(source-path) ] ;
- }
-
- local mt = [ new ac-library libpng : $(.project) : $(condition) ] ;
- $(mt).set-header $(header) ;
- $(mt).set-default-names $(names) ;
- if $(target)
- {
- $(mt).set-target $(target) ;
- }
- targets.main-target-alternative $(mt) ;
- } else {
- if $(.debug)
- {
- ECHO "notice: [libpng] Using pre-installed library" ;
- if $(condition)
- {
- ECHO "notice: [libpng] Condition" [ $(condition).raw ] ;
- }
- }
-
- local mt = [ new ac-library libpng : $(.project) : $(condition) :
- $(include-path) : $(library-path) : $(library-name) : $(root) ] ;
- $(mt).set-header $(header) ;
- $(mt).set-default-names $(names) ;
- targets.main-target-alternative $(mt) ;
- }
- .configured.$(condition) = true ;
-}

Modified: branches/release/tools/build/v2/tools/python.jam
==============================================================================
--- branches/release/tools/build/v2/tools/python.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/tools/python.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -1234,7 +1234,7 @@
     # Oddly, host-os is not in properties, so grab the default value.
     local host-os = [ feature.defaults host-os ] ;
     host-os = $(host-os:G=) ;
- if $(target-os) != $(host-os)
+ if $(target-os) != $(host-os) && $(target-os) in windows cygwin && $(host-os) in windows cygwin
     {
         PYTHONPATH = [ sequence.transform $(host-os)-to-$(target-os)-path :
             $(PYTHONPATH) ] ;

Modified: branches/release/tools/build/v2/tools/qt5.jam
==============================================================================
--- branches/release/tools/build/v2/tools/qt5.jam Tue Nov 19 12:30:34 2013 (r86767)
+++ branches/release/tools/build/v2/tools/qt5.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86768)
@@ -680,7 +680,7 @@
 #
 actions moc
 {
- $(.BINPREFIX[-1])/moc -f $(>) -o $(<) @"@($(<).rsp:E=-D$(DEFINES)$(.nl) -I$(INCLUDES:T)$(.nl))"
+ $(.BINPREFIX[-1])/moc $(>) -o $(<) @"@($(<).rsp:E=-D$(DEFINES)$(.nl) -I$(INCLUDES:T)$(.nl))"
 }
 
 # When moccing files for include only, we don't need -f, otherwise the generated

Deleted: branches/release/tools/build/v2/tools/tiff.jam
==============================================================================
--- branches/release/tools/build/v2/tools/tiff.jam 2013-11-19 14:52:02 EST (Tue, 19 Nov 2013) (r86767)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,230 +0,0 @@
-# Copyright (c) 2010 Vladimir Prus.
-# Copyright (c) 2013 Steven Watanabe
-#
-# 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)
-
-# Supports the libtiff library
-#
-# After 'using libtiff', the following targets are available:
-#
-# /libtiff//libtiff -- The libtiff library
-
-import project ;
-import ac ;
-import errors ;
-import "class" : new ;
-import targets ;
-import path ;
-import modules ;
-import errors ;
-import indirect ;
-import property ;
-import property-set ;
-
-header = tiff.h tiffio.hxx ;
-
-names = libtiff ;
-
-sources = tif_aux.c tif_close.c tif_codec.c tif_color.c tif_compress.c tif_dir.c tif_dirinfo.c
- tif_dirread.c tif_dirwrite.c tif_dumpmode.c tif_error.c tif_extension.c tif_fax3.c tif_fax3sm.c
- tif_getimage.c tif_jbig.c tif_jpeg.c tif_jpeg_12.c tif_ojpeg.c tif_flush.c tif_luv.c tif_lzw.c
- tif_next.c tif_open.c tif_packbits.c tif_pixarlog.c tif_predict.c tif_print.c tif_read.c tif_stream.cxx
- tif_swab.c tif_strip.c tif_thunder.c tif_tile.c tif_version.c tif_warning.c tif_write.c tif_zip.c ;
-
-library-id = 0 ;
-
-if --debug-configuration in [ modules.peek : ARGV ]
-{
- .debug = true ;
-}
-
-# Initializes the libtiff library.
-#
-# libtiff can be configured either to use pre-existing binaries
-# or to build the library from source.
-#
-# Options for configuring a prebuilt libtiff::
-#
-# <search>
-# The directory containing the libtiff binaries.
-# <name>
-# Overrides the default library name.
-# <include>
-# The directory containing the libtiff headers.
-#
-# If none of these options is specified, then the environmental
-# variables LIBTIFF_LIBRARY_PATH, LIBTIFF_NAME, and LIBTIFF_INCLUDE will
-# be used instead.
-#
-# Options for building libtiff from source::
-#
-# <source>
-# The libtiff source directory. Defaults to the environmental variable
-# LIBTIFF_SOURCE.
-# <tag>
-# A rule which computes the actual name of the compiled
-# libraries based on the build properties. Ignored
-# when using precompiled binaries.
-# <build-name>
-# The base name to use for the compiled library. Ignored
-# when using precompiled binaries.
-#
-# Examples::
-#
-# # Find libtiff in the default system location
-# using libtiff ;
-# # Build libtiff from source
-# using libtiff : 4.0.1 : <source>/home/steven/libtiff-4.0.1 ;
-# # Find libtiff in /usr/local
-# using libtiff : 4.0.1
-# : <include>/usr/local/include <search>/usr/local/lib ;
-# # Build libtiff from source for msvc and find
-# # prebuilt binaries for gcc.
-# using libtiff : 4.0.1 : <source>C:/Devel/src/libtiff-4.0.1 : <toolset>msvc ;
-# using libtiff : 4.0.1 : : <toolset>gcc ;
-#
-rule init (
- version ?
- # The libtiff version (currently ignored)
-
- : options *
- # A list of the options to use
-
- : requirements *
- # The requirements for the libtiff target
-
- : is-default ?
- # Default configurations are only used when libtiff
- # has not yet been configured.
- )
-{
- local caller = [ project.current ] ;
-
- if ! $(.initialized)
- {
- .initialized = true ;
-
- project.initialize $(__name__) ;
- .project = [ project.current ] ;
- project libtiff ;
- }
-
- local library-path = [ property.select <search> : $(options) ] ;
- library-path = $(library-path:G=) ;
- local include-path = [ property.select <include> : $(options) ] ;
- include-path = $(include-path:G=) ;
- local source-path = [ property.select <source> : $(options) ] ;
- source-path = $(source-path:G=) ;
- local library-name = [ property.select <name> : $(options) ] ;
- library-name = $(library-name:G=) ;
- local tag = [ property.select <tag> : $(options) ] ;
- tag = $(tag:G=) ;
- local build-name = [ property.select <build-name> : $(options) ] ;
- build-name = $(build-name:G=) ;
-
- condition = [ property-set.create $(requirements) ] ;
- condition = [ property-set.create [ $(condition).base ] ] ;
-
- local no-build-from-source ;
- # Ignore environmental ZLIB_SOURCE if this initialization
- # requested to search for a specific pre-built library.
- if $(library-path) || $(include-path) || $(library-name)
- {
- if $(source-path) || $(tag) || $(build-name)
- {
- errors.user-error "incompatible options for libtiff:"
- [ property.select <search> <include> <name> : $(options) ] "and"
- [ property.select <source> <tag> <build-name> : $(options) ] ;
- }
- else
- {
- no-build-from-source = true ;
- }
- }
-
- source-path ?= [ modules.peek : ZLIB_SOURCE ] ;
-
- if $(.configured.$(condition))
- {
- if $(is-default)
- {
- if $(.debug)
- {
- ECHO "notice: [libtiff] libtiff is already configured" ;
- }
- }
- else
- {
- errors.user-error "libtiff is already configured" ;
- }
- return ;
- }
- else if $(source-path) && ! $(no-build-from-source)
- {
- build-name ?= z ;
- library-id = [ CALC $(library-id) + 1 ] ;
- tag = [ MATCH ^@?(.*)$ : $(tag) ] ;
- if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ]
- {
- tag = [ indirect.make $(tag) : [ $(caller).project-module ] ] ;
- }
- sources = [ path.glob $(source-path) : $(sources) ] ;
- if $(.debug)
- {
- ECHO "notice: [libtiff] Building libtiff from source as $(build-name)" ;
- if $(condition)
- {
- ECHO "notice: [libtiff] Condition" [ $(condition).raw ] ;
- }
- if $(sources)
- {
- ECHO "notice: [libtiff] found libtiff source in $(source-path)" ;
- }
- else
- {
- ECHO "warning: [libtiff] could not find libtiff source in $(source-path)" ;
- }
- }
- local target ;
- if $(sources) {
- target = [ targets.create-typed-target LIB : $(.project)
- : $(build-name).$(library-id)
- : $(sources)
- : $(requirements)
- <tag>@$(tag)
- <include>$(source-path)
- <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
- <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
- <link>shared:<define>ZLIB_DLL
- :
- : <include>$(source-path) ] ;
- }
-
- local mt = [ new ac-library libtiff : $(.project) : $(condition) ] ;
- $(mt).set-header $(header) ;
- $(mt).set-default-names $(names) ;
- if $(target)
- {
- $(mt).set-target $(target) ;
- }
- targets.main-target-alternative $(mt) ;
- } else {
- if $(.debug)
- {
- ECHO "notice: [libtiff] Using pre-installed library" ;
- if $(condition)
- {
- ECHO "notice: [libtiff] Condition" [ $(condition).raw ] ;
- }
- }
-
- local mt = [ new ac-library libtiff : $(.project) : $(condition) :
- $(include-path) : $(library-path) : $(library-name) : $(root) ] ;
- $(mt).set-header $(header) ;
- $(mt).set-default-names $(names) ;
- targets.main-target-alternative $(mt) ;
- }
- .configured.$(condition) = true ;
-}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk