Boost logo

Boost-Commit :

From: ghost_at_[hidden]
Date: 2007-10-07 09:21:42


Author: vladimir_prus
Date: 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
New Revision: 39758
URL: http://svn.boost.org/trac/boost/changeset/39758

Log:
Simplify declaration and use of bjam-level actions.

Removed:
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/action.py
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/bjam.py
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/log_engine.py
Text files modified:
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/DESIGN.txt | 80 ++++++++++++++++++----
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/TODO.txt | 8 ++
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/loader.py | 15 ----
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/virtual_target.py | 20 ++---
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/engine.py | 140 +++++++++++++++++++++++++++++----------
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/main.py | 11 ++
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/tools/common.py | 44 ++++++++++--
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/tools/make.py | 2
   branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/tests/bjam/make/Jamroot | 4
   9 files changed, 231 insertions(+), 93 deletions(-)

Modified: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/DESIGN.txt
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/DESIGN.txt (original)
+++ branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/DESIGN.txt 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
@@ -1,10 +1,33 @@
 
-This document outlines internal design of the Boost.Build V2
-port to Python. This design is essentially the same
-as for Boost.Build V2 and is documented here because:
+This document outlines the goals, and internal design of the Boost.Build V2
+port to Python.
 
- - There's no single internal design document for Boost.Build V2
- - There are some slight changes
+= Goals =
+
+Using of bjam language as implementation language has two drawbacks:
+
+ - No user knows that language
+ - The language decisions (like using list of strings as primary
+ datatype) makes implementation slow and memory-hungry.
+
+The primary goal of the port is to replicate exactly the same functionality,
+and the same design and the same code, and get all the tests still work.
+The only design/code changes allowed during the port are:
+
+ - No globals -- all data that is global in existing code will be
+ kepts inside Python object that are kept inside single top-level
+ "manager" object
+ - Build actions in Python -- in case where jam code, for a given
+ command line, has both a command line proper and procedural
+ code to setup something, said procedural code will be moved in
+ Python -- while the command line will be declared using Jam syntax.
+ - Using of Python facilities. Python datatypes and builtin modules
+ will be used.
+ - Using of the property_set class. Unless required for compatibility
+ with Jamfiles, we'll be using property_set in all remaining cases
+ where raw property list is used now.
+
+= Design: Physical structure =
 
 The entire code base is divided in two parts -- Boost.Build proper and bjam.
 Boost.Build is written in Python. bjam is a build engine, written in C, and
@@ -13,9 +36,12 @@
     - Build engine functionality -- detecting out-of-date
     targets and running commands to make them out of date.
     
-The entry point is bjam, which is linked to Python interpreter.
+The entry point is bjam, which is linked to Python interpreter. On startup,
+bjam imports Python main function and calls it, from which point Python
+is in control. We can alternatively create an extension library from
+bjam, and call that from Python, but this is not important design aspect.
     
-bjam is build tool written in C, that provides
+= Design: Logical structure =
     
 There's one top-level object -- manager -- of type boost.build.Manager.
 It holds all global definitions -- set of tools, features, project
@@ -23,15 +49,39 @@
 
 - Project loading level
 - Metatargets level
-
 - Virtual targets level.
+- Engine level
+
+== Bjam engine level ==
+
+On the bjam engine level, we have bjam targets and bjam
+actions. Bjam target is just a string. It can have arbitrary
+set of (variable-name,value) pairs associated with it.
+
+
+An action has a name, and a body. Body actually specifies the
+command that should be executed, and body can make use
+of the variables defined on targets. See bjam docs for more details.
+
+In Python port, the bjam engine level is represented by the boost.build.engine
+package. The Engine class is abstract base, and BjamEngine is concrete
+implementation. The basic operation is to specify that certain targets
+are produced from other other targets using specified action. This
+is done by the 'set_update_action' method.
+
+The targets are strings, they don't need any declarations. The actions
+however do need declarations. There are two
+
+
+The bjam targets are strings, and don't need special
+declaration. The actions, however, do need special declaration, and
+there are two methods to declare a target
 
     
-Bjam <-> Python interface
-=========================
+= Bjam <-> Python interface =
+
 
-Bjam side
---------
+== Bjam side ==
 
 The EXTRA_PYTHONPATH variable, in the global module,
 should be a list with directories where Python modules
@@ -44,10 +94,8 @@
 
 This imports a python callable object from the
 specified module into bjam.
-QWERTY
 
-Python side
------------
+== Python side ==
 
 The following functions are avaiable from python, in the
 bjam module.
@@ -66,5 +114,3 @@
 
 Defines new action with specified name, body, list if bound
 variables and flags. The action is created in the global module.
-
-

Modified: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/TODO.txt
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/TODO.txt (original)
+++ branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/TODO.txt 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
@@ -30,4 +30,10 @@
 2. The current way to make rules available to Jamfiles is nasty --
 only functions defined in ProjectContext class are exported.
 
-
\ No newline at end of file
+3. boost.build.engine.engine.Engine is nasty -- any
+better Python solution?
+
+4. The error messages, so far, are truly terrible -- if Python
+code throws does something wrong we get lots of backtrace.
+
+5. Can one have nested classes in Python.
\ No newline at end of file

Deleted: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/action.py
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/action.py 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
+++ (empty file)
@@ -1,88 +0,0 @@
-# Copyright Pedro Ferreira 2005. Distributed under the Boost
-# Software License, Version 1.0. (See accompanying
-# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-from boost.build.exceptions import NoAction
-from boost.build.util.utility import split_action_id, to_seq
-
-""" Manages actions.
- Actions are accosiated with rules.
- When a rule is invoked for a target, the corresponding action is set up.
- If the target needs to be updated, the action is excuted.
- TODO: plenty to do here, regarding the actions model, namely how to support different build systems.
- See bjam and SCons.
-"""
-
-def reset ():
- """ Clear the module state. This is mainly for testing purposes.
- """
- global __all_actions
-
- __all_actions = {}
-
-reset ()
-
-def register (id, rule, actions):
- """ Registers an action 'id' for a toolset.
- 'id' is in the form 'toolset.specific_rule', where specific_rule is, e.g., compile.c++.
- 'rule' is the function to be called during the set-up phase.
- 'actions' is a sequence of string that are executed by the shell during the update phase.
- TODO: document variable expansion.
- """
- actions = to_seq (actions)
-
- if __all_actions.has_key (id):
- old = __all_actions [id]
- if not rule:
- rule = old [0]
- if not actions:
- actions = old [1]
-
- __all_actions [id] = (rule, actions)
-
-def find_action (id):
- return __find (id) [1]
-
-def find_rule (id):
- return __find (id) [0]
-
-def enumerate ():
- return __all_actions.iteritems ()
-
-def __find (id):
- """ Finds the actions associated with a rule.
- Raises NoAction is none is found.
- """
- v = __all_actions.get (id, None)
-
- if not v:
- raise NoAction ("No action found for rule '%s'" % id)
-
- return v
-
-
-class BjamActionWrapper:
- """Class which allows to use actions defined in bjam.
-
- This class is a callable which takes a name of
- bjam action and can be used inside Python. Ideally, we should
- be able to use string as action name, but current code
- requires action to be callable.
- """
-
- def __init__(self, name):
- self.name_ = name
- self.__name__ = name
-
- def __call__(self, manager, targets, sources, properties):
- """Forwards the call to bjam."""
- print "Wrapper called"
- import bjam
- bjam.call(self.name_, targets, sources, properties)
- bjam.call('DEPENDS', targets, sources)
-
- def __str__(self):
- """This is called by the Action class to determine the
- name of bjam action. Returns the one passed to __init__."""
- return self.name_
-

Modified: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/loader.py
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/loader.py (original)
+++ branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/loader.py 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
@@ -12,7 +12,6 @@
 
 import project
 from boost.build.util import path, set
-import boost.build.build.action
 import bjam
 
 
@@ -159,11 +158,6 @@
         project_module.attributes().dump()
         return project_module
 
-bjam.define_action("bla-blah", """
- cp $(>) $(<)
-""", [], 0)
-
-
 class ProjectContext:
     """Class which provides basic rules callable inside Jamfile.
 
@@ -217,15 +211,6 @@
 
     def make(self, target_name, sources, generating_rule, requirements=[]):
         import boost.build.tools.make
-
- from boost.build.build.action import BjamActionWrapper
-
- generating_rule = ["bla-blah"]
-
- boost.build.build.action.register(generating_rule[0],
- lambda a1, a2, a3, a4: None,
- "")
-
         
         boost.build.tools.make.make(self.project_module_, target_name[0],
                                     sources, generating_rule[0],

Modified: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/virtual_target.py
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/virtual_target.py (original)
+++ branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/build/virtual_target.py 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
@@ -66,7 +66,7 @@
 from boost.build.util.sequence import unique
 from boost.build.tools import common
 from boost.build.exceptions import *
-import toolset, type, action
+import toolset, type
 
 __re_starts_with_at = re.compile ('^@(.*)')
 
@@ -558,7 +558,8 @@
             # Make sure the path exists.
             engine.set_target_variable (target, 'LOCATE', file_path)
             engine.add_dependency (target, file_path)
- engine.set_update_action ('MkDir', file_path, [])
+ #engine.set_update_action ('MkDir', file_path, [], None)
+ common.mkdir(engine, file_path)
 
         else:
             # This is a source file.
@@ -670,21 +671,16 @@
         # Action name can include additional argument to rule, which should not
         # be passed to 'set-target-variables'
         toolset.set_target_variables (self.manager_, self.action_name_, actual_targets, raw_properties)
-
- rule = action.find_rule (self.action_name_)
- rule (self.manager_, actual_targets, self.actual_sources_, raw_properties)
-
+
         engine = self.manager_.engine ()
- action_name = str (self.action_name_)
-
- #if not action.exists (action_name):
- # raise NoAction ("No action defined for rule '%s'" % action_name)
         
- self.manager_.engine ().set_update_action (self.action_name_, actual_targets, self.actual_sources_)
+ self.manager_.engine ().set_update_action (self.action_name_, actual_targets, self.actual_sources_,
+ properties)
         
         # Since we set up creating action here, we also set up
         # action for cleaning up
- self.manager_.engine ().set_update_action ('Clean', 'clean', actual_targets)
+ self.manager_.engine ().set_update_action ('common.Clean', 'clean',
+ actual_targets, None)
 
         return actual_targets
 

Deleted: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/bjam.py
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/bjam.py 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
+++ (empty file)
@@ -1,23 +0,0 @@
-# Copyright Pedro Ferreira 2005. Distributed under the Boost
-# Software License, Version 1.0. (See accompanying
-# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-from boost.build.build import action
-bjam_interface = __import__('bjam')
-import log_engine
-
-
-class BjamBuildSystem (log_engine.LogBuildSystem):
- def __init__ (self):
- log_engine.LogBuildSystem.__init__ (self)
- self.all_targets_ = []
-
- def do_set_update_action (self, action_name, targets, sources):
- bjam_interface.call("set-update-action", action_name, targets, sources)
-
- def do_set_target_variable (self, target, variable, value):
- bjam_interface.call("set-target-variable", target, variable, value)
-
- def do_add_dependency (self, target, source):
- bjam_interface.call("DEPENDS", target, source)
-

Modified: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/engine.py
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/engine.py (original)
+++ branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/engine.py 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
@@ -1,14 +1,58 @@
-# Copyright Pedro Ferreira 2005. Distributed under the Boost
+# Copyright Pedro Ferreira 2005.
+# Copyright Vladimir Prus 2007.
+# Distributed under the Boost
 # Software License, Version 1.0. (See accompanying
 # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
-class BuildSystem:
- """ The abstract interface to a build system.
+bjam_interface = __import__('bjam')
+
+class BjamAction:
+ """Class representing bjam action defined from Python."""
+
+ def __init__(self, action_name, function):
+ self.action_name = action_name
+ self.function = function
+
+ def __call__(self, targets, sources, property_set):
+ if self.function:
+ self.function(targets, sources, property_set)
+ # Bjam actions defined from Python have only the command
+ # to execute, and no associated jam procedural code. So
+ # passing 'property_set' to it is not necessary.
+ bjam_interface.call("set-update-action", self.action_name,
+ targets, sources, [])
+
+class BjamNativeAction:
+ """Class representing bjam action fully defined by Jam code."""
+
+ def __init__(self, action_name):
+ self.action_name = action_name
+
+ def __call__(self, targets, sources, property_set):
+ if property_set:
+ bjam_interface.call("set-update-action", self.action_name,
+ targets, sources, property_set.raw())
+ else:
+ bjam_interface.call("set-update-action", self.action_name,
+ targets, sources, [])
+
+
+class Engine:
+ """ The abstract interface to a build engine.
+
+ For now, the naming of targets, and special handling of some
+ target variables like SEARCH and LOCATE make this class coupled
+ to bjam engine.
     """
     def __init__ (self):
- pass
+ self.actions = {}
 
     def add_dependency (self, targets, sources):
+ """Adds a dependency from 'targets' to 'sources'
+
+ Both 'targets' and 'sources' can be either list
+ of target names, or a single target name.
+ """
         if isinstance (targets, str):
             targets = [targets]
         if isinstance (sources, str):
@@ -20,7 +64,10 @@
     
     def set_target_variable (self, targets, variable, value):
         """ Sets a target variable.
- When building 'target', 'variable' will be set with 'value'
+
+ The 'variable' will be available to bjam when it decides
+ where to generate targets, and will also be available to
+ updating rule for that 'taret'.
         """
         if isinstance (targets, str):
             targets = [targets]
@@ -28,47 +75,66 @@
         for target in targets:
             self.do_set_target_variable (target, variable, value)
 
- def set_update_action (self, action_name, targets, sources):
+ def set_update_action (self, action_name, targets, sources, properties):
         """ Binds a target to the corresponding update action.
- If target needs to be updated, the action registered with action_name will be used.
+ If target needs to be updated, the action registered
+ with action_name will be used.
+ The 'action_name' must be previously registered by
+ either 'register_action' or 'register_bjam_action'
+ method.
         """
         if isinstance (targets, str):
             targets = [targets]
- self.do_set_update_action (action_name, targets, sources)
+ self.do_set_update_action (action_name, targets, sources, properties)
 
+ def register_action (self, action_name, command, bound_list = [], flags = 0,
+ function = None):
+ """Creates a new build engine action.
+
+ Creates on bjam side an action named 'action_name', with
+ 'command' as the command to be executed, 'bound_variables'
+ naming the list of variables bound when the command is executed
+ and specified flag.
+ If 'function' is not None, it should be a callable taking three
+ parameters:
+ - targets
+ - sources
+ - instance of the property_set class
+ This function will be called by set_update_action, and can
+ set additional target variables.
+ """
+ if self.actions.has_key(action_name):
+ raise "Bjam action %s is already defined" % action_name
+
+ bjam_interface.define_action(action_name, command, bound_list, flags)
+
+ self.actions[action_name] = BjamAction(action_name, function)
+
+ def register_bjam_action (self, action_name):
+ """Informs self that 'action_name' is declared in bjam.
+
+ From this point, 'action_name' is a valid argument to the
+ set_update_action method. The action_name should be callable
+ in the global module of bjam.
+ """
+ if self.actions.has_key(action_name):
+ raise "Bjam action %s is already defined" % action_name
+
+ self.actions[action_name] = BjamNativeAction(action_name)
+
     # Overridables
 
- def build (self):
- """ Builds all targets in the dependency tree.
- """
- pass
-
- def clean (self):
- """ Cleans all targets in the dependency tree.
- """
- pass
 
- def add_not_file_target (self, target):
- """ Adds a target that is not a file.
- """
- pass
+ def do_set_update_action (self, action_name, targets, sources, property_set):
+ action = self.actions.get(action_name)
+ if not action:
+ raise "No action %s was registered" % action_name
+ action(targets, sources, property_set)
 
     def do_set_target_variable (self, target, variable, value):
- """ Sets a target variable.
- When building 'target', 'variable' will be set with 'value'
- """
- pass
-
+ bjam_interface.call("set-target-variable", target, variable, value)
+
     def do_add_dependency (self, target, source):
- """ Should be redefined by base classes.
- Sets a dependency between one target and one source.
- """
- pass
-
- def do_set_update_action (self, action_name, targets, sources):
- """ Binds a target to the corresponding update action.
- If target needs to be updated, the action registered with action_name will be used.
- """
- pass
+ bjam_interface.call("DEPENDS", target, source)
          
-
\ No newline at end of file
+

Deleted: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/log_engine.py
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/engine/log_engine.py 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
+++ (empty file)
@@ -1,39 +0,0 @@
-# Copyright Pedro Ferreira 2005. Distributed under the Boost
-# Software License, Version 1.0. (See accompanying
-# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-from boost.build.engine.engine import BuildSystem
-
-class LogBuildSystem (BuildSystem):
- """ A build system for testing purposes. Only stores the data.
- """
- def __init__ (self):
- self.variables_ = {}
- self.dependencies_ = {}
- self.actions_bindings_ = []
-
- def do_set_target_variable (self, target, variable, value):
- if not self.variables_.has_key (target):
- self.variables_ [target] = {}
-
- if not self.variables_ [target].has_key (variable):
- self.variables_ [target][variable] = []
-
- self.variables_ [target][variable].append (value)
-
- def do_add_dependency (self, target, source):
- if not self.dependencies_.has_key (target):
- self.dependencies_ [target] = []
- self.dependencies_ [target].append (source)
-
- def do_set_update_action (self, action_name, targets, sources):
- self.actions_bindings_.append ((action_name, targets, sources))
-
- def variables (self):
- return self.variables_
-
- def dependencies (self):
- return self.dependencies_
-
- def action_bindings (self):
- return self.actions_bindings_

Modified: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/main.py
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/main.py (original)
+++ branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/main.py 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
@@ -6,18 +6,23 @@
 
 import bjam
 import sys
-from boost.build.engine.bjam import *
+from boost.build.engine.engine import Engine
 from boost.build.manager import Manager
 from boost.build.build.loader import ProjectLoader
 import boost.build.tools.builtin
 from boost.build.build import property_set
 
+import boost.build.tools.common
+
 def main(argv):
     print "Starting Boost.Build V2/Python"
     sys.argv = argv
 
- build_system = BjamBuildSystem()
- manager = Manager(build_system)
+ engine = Engine()
+ manager = Manager(engine)
+
+ boost.build.tools.common.init(manager)
+
     loader = ProjectLoader(manager.projects());
     project_here = loader.load('.')
 

Modified: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/tools/common.py
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/tools/common.py (original)
+++ branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/tools/common.py 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
@@ -8,8 +8,9 @@
 """
 
 import re
+import bjam
 
-from boost.build.build import action, feature
+from boost.build.build import feature
 from boost.build.util.utility import *
 from boost.build.util import path
 
@@ -35,11 +36,6 @@
     
 reset ()
 
-# TODO: check this.
-action.register ('Clean', None, 'rm -rf "$(>)"')
-action.register ('MkDir', None, 'mkdir -p "$(<)"')
-
-
 def check_init_parameters (toolset, *args):
     """ The rule checks toolset parameters. Each trailing parameter
         should be a tuple of parameter name and parameter value.
@@ -541,4 +537,38 @@
 ###
 ### modules.poke os : name : $(save-os) ;
 ###
-### }
+### }
+
+# FIXME: global variable
+made_dirs = {}
+
+def mkdir(engine, path_target):
+ """Creates dependencies that cause directory 'path_target' to be created"""
+
+ # If dir exists, don't update it
+ # Do this even for $(DOT).
+ bjam.call("NOUPDATE", path_target)
+
+ if path_target != "." and not made_dirs.has_key(path_target):
+ made_dirs[path_target] = 1
+ engine.set_update_action("common.MkDir1", path_target, [], None)
+
+ parent = os.path.dirname(path_target)
+ # Part of original Jam code, supposed to prevent
+ # calling mkdir on drive letters.
+ if len(parent) == 2 and parent[1] == ':':
+ parent = None
+ if len(parent) == 3 and parent[1] == ':' and parent[2] == '\\':
+ parent = None
+
+ if parent and parent != path_target:
+ engine.add_dependency(path_target, parent)
+ mkdir(engine, parent)
+ elif parent:
+ bjam.call("NOTFILE", parent)
+
+def init(manager):
+ engine = manager.engine()
+
+ engine.register_action ("common.MkDir1", 'mkdir "$(<)"')
+ engine.register_action ("common.Clean", 'rm -rf "$(>)"')

Modified: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/tools/make.py
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/tools/make.py (original)
+++ branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/boost/build/tools/make.py 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
@@ -29,6 +29,8 @@
     """ Declares the 'make' main target.
     """
     targets = project.manager ().targets ()
+ engine = project.manager().engine()
+ engine.register_bjam_action(generating_rule)
     
     targets.main_target_alternative (MakeTarget (project.target (),
         target_name,

Modified: branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/tests/bjam/make/Jamroot
==============================================================================
--- branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/tests/bjam/make/Jamroot (original)
+++ branches/BOOST_BUILD_PYTHON/boost/tools/build/v2/python/tests/bjam/make/Jamroot 2007-10-07 09:21:41 EDT (Sun, 07 Oct 2007)
@@ -1,6 +1,8 @@
 
 make a : a.cpp : $(__name__).copy ;
 
+FOO = 1 ;
+
 rule copy ( targets : sources : properties * )
 {
     ECHO "XXXXXXXXXXX copy $(targets) : $(sources) : $(properties)" ;
@@ -8,5 +10,5 @@
 
 actions copy
 {
- asdascp $(>) $(<)
+ cp $(FOO) $(>) $(<)
 }


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