Boost logo

Boost-Commit :

From: ghost_at_[hidden]
Date: 2007-10-14 05:19:52


Author: vladimir_prus
Date: 2007-10-14 05:19:52 EDT (Sun, 14 Oct 2007)
New Revision: 40007
URL: http://svn.boost.org/trac/boost/changeset/40007

Log:
Port 'using' and 'import' Jamfile rules.

Added:
   branches/build/python_port/python/tests/bjam/make/tool.py (contents, props changed)
   branches/build/python_port/python/tests/bjam/make/util.py (contents, props changed)
Text files modified:
   branches/build/python_port/python/boost/build/build/project.py | 154 ++++++++++++++++++++++++---------------
   branches/build/python_port/python/boost/build/manager.py | 4 +
   branches/build/python_port/python/tests/bjam/make/Jamroot | 7 +
   3 files changed, 107 insertions(+), 58 deletions(-)

Modified: branches/build/python_port/python/boost/build/build/project.py
==============================================================================
--- branches/build/python_port/python/boost/build/build/project.py (original)
+++ branches/build/python_port/python/boost/build/build/project.py 2007-10-14 05:19:52 EDT (Sun, 14 Oct 2007)
@@ -47,6 +47,7 @@
 import sys
 import os
 import string
+import imp
 
 class ProjectRegistry:
 
@@ -81,6 +82,10 @@
         # Map from project module to target for the project
         self.module2target = {}
 
+ # Map from names to Python modules, for modules loaded
+ # via 'using' and 'import' rules in Jamfiles.
+ self.loaded_tool_modules_ = {}
+
         # Map from project target to the list of
         # (id,location) pairs corresponding to all 'use-project'
         # invocations.
@@ -548,6 +553,49 @@
             
         return result
 
+ def load_module(self, name, extra_path=None):
+ """Find a Python module called 'name' in Boost.Build search
+ path and load it. The module is not entered in sys.modules.
+ The motivation here is to have disjoint namespace of modules
+ loaded via 'import/using' in Jamfile, and ordinary Python
+ modules. We don't want 'using foo' in Jamfile to load ordinary
+ Python module 'foo' which is going to not work. And we
+ also don't want 'import foo' in regular Python module to
+ accidentally grab module named foo that is internal to
+ Boost.Build and intended to provide interface to Jamfiles."""
+
+ existing = self.loaded_tool_modules_.get(name)
+ if existing:
+ return existing
+
+ path = extra_path
+ if not path:
+ path = []
+ path.extend(self.manager.boost_build_path())
+ location = None
+ for p in path:
+ l = os.path.join(p, name + ".py")
+ if os.path.exists(l):
+ location = l
+ break
+
+ if not location:
+ self.manager.errors()("Cannot find module '%s'" % name)
+
+ mname = "__build_build_temporary__"
+ file = open(location)
+ try:
+ # TODO: this means we'll never make use of .pyc module,
+ # which might be a problem, or not.
+ module = imp.load_module(mname, file, os.path.basename(location),
+ (".py", "r", imp.PY_SOURCE))
+ del sys.modules[mname]
+ self.loaded_tool_modules_[name] = module
+ return module
+ finally:
+ file.close()
+
+
 
 # FIXME:
 # Defines a Boost.Build extension project. Such extensions usually
@@ -720,7 +768,10 @@
             # while using self.__dict__[r] would give unbound one.
             v = getattr(self, n)
             if callable(v):
- n = string.replace(n, "_", "-")
+ if n == "import_":
+ n = "import"
+ else:
+ n = string.replace(n, "_", "-")
                 print "Importing '%s' to bjam" % n
                 bjam.import_rule(project_module, n, v)
 
@@ -829,66 +880,53 @@
                                            wildcards, excludes, "glob_tree")
     
 
-# FIXME
-## # This module defines rules common to all projects
-## module project-rules
-## {
-## rule using ( toolset-module : * )
-## {
-## import toolset ;
-## import modules ;
-## import project ;
-
-## # The module referred by 'using' can be placed in
-## # the same directory as Jamfile, and the user
-## # will expect the module to be found even though
-## # the directory is not in BOOST_BUILD_PATH.
-## # So temporary change the search path.
-## local x = [ modules.peek : BOOST_BUILD_PATH ] ;
-## local caller = [ modules.binding $(__name__) ] ;
-## modules.poke : BOOST_BUILD_PATH : $(caller:D) $(x) ;
-## toolset.using $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
-## modules.poke : BOOST_BUILD_PATH : $(x) ;
-
-## # The above might have clobbered .current-project
-## # Restore the the right value.
-## modules.poke project : .current-project
-## : [ project.target $(__name__) ] ;
-## }
-
-## import modules ;
-
-## rule import ( * : * : * )
-## {
-## modules.import project ;
-
-## local caller = [ CALLER_MODULE ] ;
-## local saved = [ modules.peek project : .current-project ] ;
-## module $(caller)
-## {
-## modules.import $(1) : $(2) : $(3) ;
-## }
-## modules.poke project : .current-project : $(saved) ;
-## }
+ def using(self, toolset, *args):
+ # The module referred by 'using' can be placed in
+ # the same directory as Jamfile, and the user
+ # will expect the module to be found even though
+ # the directory is not in BOOST_BUILD_PATH.
+ # So temporary change the search path.
+ jamfile_module = self.registry.current().project_module()
+ attributes = self.registry.attributes(jamfile_module)
+ location = attributes.get("location")
 
-
-
+ m = self.registry.load_module(toolset[0], [location])
+ m.init(*args)
 
-## }
-
 
+ def import_(self, name, names_to_import=None, local_names=None):
 
+ name = name[0]
+ jamfile_module = self.registry.current().project_module()
+ attributes = self.registry.attributes(jamfile_module)
+ location = attributes.get("location")
+
+ m = self.registry.load_module(name, [location])
+
+ for f in m.__dict__:
+ v = m.__dict__[f]
+ if callable(v):
+ bjam.import_rule(jamfile_module, name + "." + f, v)
 
+ if names_to_import:
+ if not local_names:
+ local_names = names_to_import
+
+ if len(names_to_import) != len(local_names):
+ self.registry.manager.errors()(
+"""The number of names to import and local names do not match.""")
+
+ for n, l in zip(names_to_import, local_names):
+ bjam.import_rule(jamfile_module, l, m.__dict__[n])
+
+ def conditional(self, condition, requirements):
+ """Calculates conditional requirements for multiple requirements
+ at once. This is a shorthand to be reduce duplication and to
+ keep an inline declarative syntax. For example:
+
+ lib x : x.cpp : [ conditional <toolset>gcc <variant>debug :
+ <define>DEBUG_EXCEPTION <define>DEBUG_TRACE ] ;
+ """
 
-## # Calculates conditional requirements for multiple requirements
-## # at once. This is a shorthand to be reduce duplication and to
-## # keep an inline declarative syntax. For example:
-## #
-## # lib x : x.cpp : [ conditional <toolset>gcc <variant>debug :
-## # <define>DEBUG_EXCEPTION <define>DEBUG_TRACE ] ;
-## #
-## rule conditional ( condition + : requirements * )
-## {
-## return $(condition:J=,):$(requirements) ;
-## }
-## }
+ c = string.join(condition, ",")
+ return [c + ":" + r for r in requirements]

Modified: branches/build/python_port/python/boost/build/manager.py
==============================================================================
--- branches/build/python_port/python/boost/build/manager.py (original)
+++ branches/build/python_port/python/boost/build/manager.py 2007-10-14 05:19:52 EDT (Sun, 14 Oct 2007)
@@ -33,6 +33,7 @@
         self.logger_ = NullLogger ()
         self.scanners_ = ScannerRegistry (self)
         self.argv_ = bjam.variable("ARGV")
+ self.boost_build_path_ = bjam.variable("BOOST_BUILD_PATH")
         self.errors_ = Errors()
         
         # Object Map.
@@ -74,6 +75,9 @@
     def getenv(self, name):
         return bjam.variable(name)
 
+ def boost_build_path(self):
+ return self.boost_build_path_
+
     def register_object (self, value):
         """ Stores an object in a map and returns a key that can be used to retrieve it.
         """

Modified: branches/build/python_port/python/tests/bjam/make/Jamroot
==============================================================================
--- branches/build/python_port/python/tests/bjam/make/Jamroot (original)
+++ branches/build/python_port/python/tests/bjam/make/Jamroot 2007-10-14 05:19:52 EDT (Sun, 14 Oct 2007)
@@ -1,4 +1,11 @@
 
+using tool : 1.0 ;
+using tool : 2.0 ;
+import util : say2 : say2local ;
+
+util.say "hi" ;
+say2local "howdy" ;
+
 project test : requirements <variant>release ;
 
 constant FOO : foo ;

Added: branches/build/python_port/python/tests/bjam/make/tool.py
==============================================================================
--- (empty file)
+++ branches/build/python_port/python/tests/bjam/make/tool.py 2007-10-14 05:19:52 EDT (Sun, 14 Oct 2007)
@@ -0,0 +1,5 @@
+
+print "tool.py is being loaded"
+
+def init(version):
+ print "Tool version %s initialized" % version
\ No newline at end of file

Added: branches/build/python_port/python/tests/bjam/make/util.py
==============================================================================
--- (empty file)
+++ branches/build/python_port/python/tests/bjam/make/util.py 2007-10-14 05:19:52 EDT (Sun, 14 Oct 2007)
@@ -0,0 +1,6 @@
+
+def say(foo):
+ print "saying", foo
+
+def say2(foo):
+ print "saying 2", foo
\ No newline at end of file


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