hackedteam/core-android-market

View on GitHub
src/libbson/boost/boost_1_53_0/tools/build/v2/build/project.ann.py

Summary

Maintainability
D
2 days
Test Coverage
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000   1) # Status: being ported by Vladimir Prus
ddc17f01 (vladimir_prus 2007-10-26 14:57:56 +0000   2) # Base revision: 40480
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000   3) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000   4) # Copyright 2002, 2003 Dave Abrahams 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000   5) # Copyright 2002, 2005, 2006 Rene Rivera 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000   6) # Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000   7) # Distributed under the Boost Software License, Version 1.0. 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000   8) # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000   9) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  10) #  Implements project representation and loading.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  11) #   Each project is represented by 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  12) #   - a module where all the Jamfile content live. 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  13) #   - an instance of 'project-attributes' class.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  14) #     (given module name, can be obtained by 'attributes' rule)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  15) #   - an instance of 'project-target' class (from targets.jam)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  16) #     (given a module name, can be obtained by 'target' rule)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  17) #
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  18) #  Typically, projects are created as result of loading Jamfile, which is
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  19) #  do by rules 'load' and 'initialize', below. First, module for Jamfile
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  20) #  is loaded and new project-attributes instance is created. Some rules
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  21) #  necessary for project are added to the module (see 'project-rules' module)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  22) #  at the bottom of this file.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  23) #  Default project attributes are set (inheriting attributes of parent project, if
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  24) #  it exists). After that, Jamfile is read. It can declare its own attributes,
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  25) #  via 'project' rule, which will be combined with already set attributes.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  26) #
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  27) #
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  28) #  The 'project' rule can also declare project id, which will be associated with 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  29) #  the project module.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  30) #
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  31) #  There can also be 'standalone' projects. They are created by calling 'initialize'
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  32) #  on arbitrary module, and not specifying location. After the call, the module can
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  33) #  call 'project' rule, declare main target and behave as regular projects. However,
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  34) #  since it's not associated with any location, it's better declare only prebuilt 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  35) #  targets.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  36) #
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  37) #  The list of all loaded Jamfile is stored in variable .project-locations. It's possible
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  38) #  to obtain module name for a location using 'module-name' rule. The standalone projects
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  39) #  are not recorded, the only way to use them is by project id.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  40) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  41) import b2.util.path
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000  42) from b2.build import property_set, property
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000  43) from b2.build.errors import ExceptionWithUserContext
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  44) import b2.build.targets
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  45) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  46) import bjam
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  47) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  48) import re
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  49) import sys
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  50) import os
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  51) import string
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000  52) import imp
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000  53) import traceback
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  54) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  55) class ProjectRegistry:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  56) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  57)     def __init__(self, manager, global_build_dir):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  58)         self.manager = manager
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  59)         self.global_build_dir = None
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000  60)         self.project_rules_ = ProjectRules(self)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  61) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000  62)         # The target corresponding to the project being loaded now
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  63)         self.current_project = None
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  64)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  65)         # The set of names of loaded project modules
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  66)         self.jamfile_modules = {}
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  67) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  68)         # Mapping from location to module name
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  69)         self.location2module = {}
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  70) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  71)         # Mapping from project id to project module
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  72)         self.id2module = {}
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  73) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  74)         # Map from Jamfile directory to parent Jamfile/Jamroot
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  75)         # location.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  76)         self.dir2parent_jamfile = {}
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  77) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  78)         # Map from directory to the name of Jamfile in
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  79)         # that directory (or None).
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  80)         self.dir2jamfile = {}
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  81) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  82)         # Map from project module to attributes object.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  83)         self.module2attributes = {}
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  84) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  85)         # Map from project module to target for the project
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  86)         self.module2target = {}
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  87) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000  88)         # Map from names to Python modules, for modules loaded
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000  89)         # via 'using' and 'import' rules in Jamfiles.
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000  90)         self.loaded_tool_modules_ = {}
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000  91) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000  92)         # Map from project target to the list of
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000  93)         # (id,location) pairs corresponding to all 'use-project'
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000  94)         # invocations.
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000  95)         # TODO: should not have a global map, keep this
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000  96)         # in ProjectTarget.
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000  97)         self.used_projects = {}
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000  98) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000  99)         self.saved_current_project = []
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 100) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 101)         self.JAMROOT = self.manager.getenv("JAMROOT");
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 102) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 103)         # Note the use of character groups, as opposed to listing
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 104)         # 'Jamroot' and 'jamroot'. With the latter, we'd get duplicate
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 105)         # matches on windows and would have to eliminate duplicates.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 106)         if not self.JAMROOT:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 107)             self.JAMROOT = ["project-root.jam", "[Jj]amroot", "[Jj]amroot.jam"]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 108) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 109)         # Default patterns to search for the Jamfiles to use for build
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 110)         # declarations.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 111)         self.JAMFILE = self.manager.getenv("JAMFILE")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 112) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 113)         if not self.JAMFILE:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 114)             self.JAMFILE = ["[Bb]uild.jam", "[Jj]amfile.v2", "[Jj]amfile",
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 115)                             "[Jj]amfile.jam"]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 116) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 117) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 118)     def load (self, jamfile_location):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 119)         """Loads jamfile at the given location. After loading, project global
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 120)         file and jamfile needed by the loaded one will be loaded recursively.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 121)         If the jamfile at that location is loaded already, does nothing.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 122)         Returns the project module for the Jamfile."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 123) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 124)         absolute = os.path.join(os.getcwd(), jamfile_location)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 125)         absolute = os.path.normpath(absolute)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 126)         jamfile_location = b2.util.path.relpath(os.getcwd(), absolute)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 127) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 128)         if "--debug-loading" in self.manager.argv():
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 129)             print "Loading Jamfile at '%s'" % jamfile_location
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 130) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 131)             
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 132)         mname = self.module_name(jamfile_location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 133)         # If Jamfile is already loaded, don't try again.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 134)         if not mname in self.jamfile_modules:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 135)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 136)             self.load_jamfile(jamfile_location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 137)                 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 138)             # We want to make sure that child project are loaded only
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 139)             # after parent projects. In particular, because parent projects
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 140)             # define attributes whch are inherited by children, and we don't
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 141)             # want children to be loaded before parents has defined everything.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 142)             #
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 143)             # While "build-project" and "use-project" can potentially refer
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 144)             # to child projects from parent projects, we don't immediately
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 145)             # load child projects when seing those attributes. Instead,
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 146)             # we record the minimal information that will be used only later.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 147)             
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 148)             self.load_used_projects(mname)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 149)              
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 150)         return mname
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 151) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 152)     def load_used_projects(self, module_name):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 153)         # local used = [ modules.peek $(module-name) : .used-projects ] ;
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 154)         used = self.used_projects[module_name]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 155)     
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 156)         location = self.attribute(module_name, "location")
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 157)         for u in used:
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 158)             id = u[0]
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 159)             where = u[1]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 160) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 161)             self.use(id, os.path.join(location, where))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 162) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 163)     def load_parent(self, location):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 164)         """Loads parent of Jamfile at 'location'.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 165)         Issues an error if nothing is found."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 166) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 167)         found = b2.util.path.glob_in_parents(
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 168)             location, self.JAMROOT + self.JAMFILE) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 169) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 170)         if not found:
1674e2d9 (jhunold       2008-08-08 19:52:05 +0000 171)             print "error: Could not find parent for project at '%s'" % location
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 172)             print "error: Did not find Jamfile or project-root.jam in any parent directory."
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 173)             sys.exit(1)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 174)     
49c03622 (jhunold       2008-07-23 09:57:41 +0000 175)         return self.load(os.path.dirname(found[0]))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 176) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 177)     def act_as_jamfile(self, module, location):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 178)         """Makes the specified 'module' act as if it were a regularly loaded Jamfile 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 179)         at 'location'. If Jamfile is already located for that location, it's an 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 180)         error."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 181) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 182)         if self.module_name(location) in self.jamfile_modules:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 183)             self.manager.errors()(
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 184)                 "Jamfile was already loaded for '%s'" % location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 185)     
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 186)         # Set up non-default mapping from location to module.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 187)         self.location2module[location] = module
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 188)     
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 189)         # Add the location to the list of project locations
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 190)         # so that we don't try to load Jamfile in future
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 191)         self.jamfile_modules.append(location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 192)     
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 193)         self.initialize(module, location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 194) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 195)     def find(self, name, current_location):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 196)         """Given 'name' which can be project-id or plain directory name,
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 197)         return project module corresponding to that id or directory.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 198)         Returns nothing of project is not found."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 199) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 200)         project_module = None
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 201) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 202)         # Try interpreting name as project id.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 203)         if name[0] == '/':
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 204)             project_module = self.id2module.get(name)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 205) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 206)         if not project_module:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 207)             location = os.path.join(current_location, name)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 208)             # If no project is registered for the given location, try to
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 209)             # load it. First see if we have Jamfile. If not we might have project
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 210)             # root, willing to act as Jamfile. In that case, project-root
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 211)             # must be placed in the directory referred by id.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 212)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 213)             project_module = self.module_name(location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 214)             if not project_module in self.jamfile_modules and \
49c03622 (jhunold       2008-07-23 09:57:41 +0000 215)                b2.util.path.glob([location], self.JAMROOT + self.JAMFILE):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 216)                 project_module = self.load(location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 217) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 218)         return project_module
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 219) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 220)     def module_name(self, jamfile_location):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 221)         """Returns the name of module corresponding to 'jamfile-location'.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 222)         If no module corresponds to location yet, associates default
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 223)         module name with that location."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 224)         module = self.location2module.get(jamfile_location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 225)         if not module:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 226)             # Root the path, so that locations are always umbiguious.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 227)             # Without this, we can't decide if '../../exe/program1' and '.'
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 228)             # are the same paths, or not.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 229)             jamfile_location = os.path.realpath(
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 230)                 os.path.join(os.getcwd(), jamfile_location))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 231)             module = "Jamfile<%s>" % jamfile_location
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 232)             self.location2module[jamfile_location] = module
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 233)         return module
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 234) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 235)     def find_jamfile (self, dir, parent_root=0, no_errors=0):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 236)         """Find the Jamfile at the given location. This returns the
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 237)         exact names of all the Jamfiles in the given directory. The optional
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 238)         parent-root argument causes this to search not the given directory
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 239)         but the ones above it up to the directory given in it."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 240)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 241)         # Glob for all the possible Jamfiles according to the match pattern.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 242)         #
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 243)         jamfile_glob = None
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 244)         if parent_root:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 245)             parent = self.dir2parent_jamfile.get(dir)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 246)             if not parent:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 247)                 parent = b2.util.path.glob_in_parents(dir,
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 248)                                                                self.JAMFILE)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 249)                 self.dir2parent_jamfile[dir] = parent
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 250)             jamfile_glob = parent
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 251)         else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 252)             jamfile = self.dir2jamfile.get(dir)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 253)             if not jamfile:
49c03622 (jhunold       2008-07-23 09:57:41 +0000 254)                 jamfile = b2.util.path.glob([dir], self.JAMFILE)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 255)                 self.dir2jamfile[dir] = jamfile
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 256)             jamfile_glob = jamfile
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 257) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 258)         if len(jamfile_glob):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 259)             # Multiple Jamfiles found in the same place. Warn about this.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 260)             # And ensure we use only one of them.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 261)             # As a temporary convenience measure, if there's Jamfile.v2 amount
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 262)             # found files, suppress the warning and use it.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 263)             #
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 264)             pattern = "(.*[Jj]amfile\\.v2)|(.*[Bb]uild\\.jam)"
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 265)             v2_jamfiles = [x for x in jamfile_glob if re.match(pattern, x)]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 266)             if len(v2_jamfiles) == 1:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 267)                 jamfile_glob = v2_jamfiles
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 268)             else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 269)                 print """warning: Found multiple Jamfiles at '%s'!
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 270) Loading the first one: '%s'.""" % (dir, jamfile_glob[0])
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 271)     
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 272)         # Could not find it, error.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 273)         if not no_errors and not jamfile_glob:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 274)             self.manager.errors()(
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 275)                 """Unable to load Jamfile.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 276) Could not find a Jamfile in directory '%s'
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 277) Attempted to find it with pattern '%s'.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 278) Please consult the documentation at 'http://boost.org/b2.'."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 279)                 % (dir, string.join(self.JAMFILE)))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 280) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 281)         return jamfile_glob[0]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 282)     
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 283)     def load_jamfile(self, dir):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 284)         """Load a Jamfile at the given directory. Returns nothing.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 285)         Will attempt to load the file as indicated by the JAMFILE patterns.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 286)         Effect of calling this rule twice with the same 'dir' is underfined."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 287)       
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 288)         # See if the Jamfile is where it should be.
49c03622 (jhunold       2008-07-23 09:57:41 +0000 289)         jamfile_to_load = b2.util.path.glob([dir], self.JAMROOT)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 290)         if not jamfile_to_load:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 291)             jamfile_to_load = self.find_jamfile(dir)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 292)         else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 293)             jamfile_to_load = jamfile_to_load[0]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 294)             
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 295)         # The module of the jamfile.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 296)         dir = os.path.realpath(os.path.dirname(jamfile_to_load))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 297)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 298)         jamfile_module = self.module_name (dir)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 299) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 300)         # Initialize the jamfile module before loading.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 301)         #    
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 302)         self.initialize(jamfile_module, dir, os.path.basename(jamfile_to_load))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 303) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 304)         saved_project = self.current_project
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 305) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 306)         self.used_projects[jamfile_module] = []
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 307)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 308)         # Now load the Jamfile in it's own context.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 309)         # Initialization might have load parent Jamfiles, which might have
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 310)         # loaded the current Jamfile with use-project. Do a final check to make
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 311)         # sure it's not loaded already.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 312)         if not jamfile_module in self.jamfile_modules:
49c03622 (jhunold       2008-07-23 09:57:41 +0000 313)             self.jamfile_modules[jamfile_module] = True
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 314) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 315)             # FIXME:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 316)             # mark-as-user $(jamfile-module) ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 317) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 318)             bjam.call("load", jamfile_module, jamfile_to_load)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 319)             basename = os.path.basename(jamfile_to_load)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 320)                         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 321)         # Now do some checks
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 322)         if self.current_project != saved_project:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 323)             self.manager.errors()(
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 324) """The value of the .current-project variable
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 325) has magically changed after loading a Jamfile.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 326) This means some of the targets might be defined a the wrong project.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 327) after loading %s
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 328) expected value %s
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 329) actual value %s""" % (jamfile_module, saved_project, self.current_project))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 330)           
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 331)         if self.global_build_dir:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 332)             id = self.attribute(jamfile_module, "id")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 333)             project_root = self.attribute(jamfile_module, "project-root")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 334)             location = self.attribute(jamfile_module, "location")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 335) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 336)             if location and project_root == dir:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 337)                 # This is Jamroot
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 338)                 if not id:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 339)                     # FIXME: go via errors module, so that contexts are
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 340)                     # shown?
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 341)                     print "warning: the --build-dir option was specified"
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 342)                     print "warning: but Jamroot at '%s'" % dir
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 343)                     print "warning: specified no project id"
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 344)                     print "warning: the --build-dir option will be ignored"
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 345) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 346) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 347)     def load_standalone(self, jamfile_module, file):
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 348)         """Loads 'file' as standalone project that has no location
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 349)         associated with it.  This is mostly useful for user-config.jam,
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 350)         which should be able to define targets, but although it has
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 351)         some location in filesystem, we don't want any build to
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 352)         happen in user's HOME, for example.
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 353) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 354)         The caller is required to never call this method twice on
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 355)         the same file.
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 356)         """
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 357) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 358)         self.initialize(jamfile_module)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 359)         self.used_projects[jamfile_module] = []
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 360)         bjam.call("load", jamfile_module, file)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 361)         self.load_used_projects(jamfile_module)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 362)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 363)     def is_jamroot(self, basename):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 364)         match = [ pat for pat in self.JAMROOT if re.match(pat, basename)]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 365)         if match:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 366)             return 1
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 367)         else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 368)             return 0
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 369) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 370)     def initialize(self, module_name, location=None, basename=None):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 371)         """Initialize the module for a project.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 372)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 373)         module-name is the name of the project module.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 374)         location is the location (directory) of the project to initialize.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 375)                  If not specified, stanalone project will be initialized
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 376)         """
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 377) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 378)         if "--debug-loading" in self.manager.argv():
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 379)             print "Initializing project '%s'" % module_name
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 380) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 381)         # TODO: need to consider if standalone projects can do anything but defining
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 382)         # prebuilt targets. If so, we need to give more sensible "location", so that
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 383)         # source paths are correct.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 384)         if not location:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 385)             location = ""
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 386)         else:
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 387)             location = b2.util.path.relpath(os.getcwd(), location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 388) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 389)         attributes = ProjectAttributes(self.manager, location, module_name)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 390)         self.module2attributes[module_name] = attributes
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 391) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 392)         if location:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 393)             attributes.set("source-location", location, exact=1)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 394)         else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 395)             attributes.set("source-location", "", exact=1)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 396) 
49c03622 (jhunold       2008-07-23 09:57:41 +0000 397)         attributes.set("requirements", property_set.empty(), exact=True)
49c03622 (jhunold       2008-07-23 09:57:41 +0000 398)         attributes.set("usage-requirements", property_set.empty(), exact=True)
49c03622 (jhunold       2008-07-23 09:57:41 +0000 399)         attributes.set("default-build", [], exact=True)
49c03622 (jhunold       2008-07-23 09:57:41 +0000 400)         attributes.set("projects-to-build", [], exact=True)
49c03622 (jhunold       2008-07-23 09:57:41 +0000 401)         attributes.set("project-root", None, exact=True)
49c03622 (jhunold       2008-07-23 09:57:41 +0000 402)         attributes.set("build-dir", None, exact=True)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 403)         
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 404)         self.project_rules_.init_project(module_name)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 405) 
49c03622 (jhunold       2008-07-23 09:57:41 +0000 406)         jamroot = False
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 407) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 408)         parent_module = None;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 409)         if module_name == "site-config":
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 410)             # No parent
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 411)             pass
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 412)         elif module_name == "user-config":
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 413)             parent_module = "site-config"
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 414)         elif location and not self.is_jamroot(basename):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 415)             # We search for parent/project-root only if jamfile was specified 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 416)             # --- i.e
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 417)             # if the project is not standalone.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 418)             parent_module = self.load_parent(location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 419)         else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 420)             # It's either jamroot, or standalone project.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 421)             # If it's jamroot, inherit from user-config.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 422)             if location:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 423)                 parent_module = "user-config" ;                
49c03622 (jhunold       2008-07-23 09:57:41 +0000 424)                 jamroot = True ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 425)                 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 426)         if parent_module:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 427)             self.inherit_attributes(module_name, parent_module)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 428)             attributes.set("parent-module", parent_module, exact=1)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 429) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 430)         if jamroot:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 431)             attributes.set("project-root", location, exact=1)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 432)                                 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 433)         parent = None
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 434)         if parent_module:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 435)             parent = self.target(parent_module)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 436) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 437)         if not self.module2target.has_key(module_name):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 438)             target = b2.build.targets.ProjectTarget(self.manager,
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 439)                 module_name, module_name, parent,
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 440)                 self.attribute(module_name,"requirements"),
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 441)                 # FIXME: why we need to pass this? It's not
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 442)                 # passed in jam code.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 443)                 self.attribute(module_name, "default-build"))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 444)             self.module2target[module_name] = target
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 445) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 446)         self.current_project = self.target(module_name)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 447) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 448)     def inherit_attributes(self, project_module, parent_module):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 449)         """Make 'project-module' inherit attributes of project
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 450)         root and parent module."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 451) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 452)         attributes = self.module2attributes[project_module]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 453)         pattributes = self.module2attributes[parent_module]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 454)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 455)         # Parent module might be locationless user-config.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 456)         # FIXME:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 457)         #if [ modules.binding $(parent-module) ]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 458)         #{        
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 459)         #    $(attributes).set parent : [ path.parent 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 460)         #                                 [ path.make [ modules.binding $(parent-module) ] ] ] ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 461)         #    }
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 462)         
49c03622 (jhunold       2008-07-23 09:57:41 +0000 463)         attributes.set("project-root", pattributes.get("project-root"), exact=True)
49c03622 (jhunold       2008-07-23 09:57:41 +0000 464)         attributes.set("default-build", pattributes.get("default-build"), exact=True)
49c03622 (jhunold       2008-07-23 09:57:41 +0000 465)         attributes.set("requirements", pattributes.get("requirements"), exact=True)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 466)         attributes.set("usage-requirements",
cde6f09a (vladimir_prus 2007-10-19 23:12:33 +0000 467)                        pattributes.get("usage-requirements"), exact=1)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 468) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 469)         parent_build_dir = pattributes.get("build-dir")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 470)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 471)         if parent_build_dir:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 472)         # Have to compute relative path from parent dir to our dir
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 473)         # Convert both paths to absolute, since we cannot
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 474)         # find relative path from ".." to "."
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 475) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 476)              location = attributes.get("location")
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 477)              parent_location = pattributes.get("location")
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 478) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 479)              our_dir = os.path.join(os.getcwd(), location)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 480)              parent_dir = os.path.join(os.getcwd(), parent_location)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 481) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 482)              build_dir = os.path.join(parent_build_dir,
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 483)                                       b2.util.path.relpath(parent_dir,
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 484)                                                                     our_dir))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 485) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 486)     def register_id(self, id, module):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 487)         """Associate the given id with the given project module."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 488)         self.id2module[id] = module
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 489) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 490)     def current(self):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 491)         """Returns the project which is currently being loaded."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 492)         return self.current_project
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 493) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 494)     def push_current(self, project):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 495)         """Temporary changes the current project to 'project'. Should
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 496)         be followed by 'pop-current'."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 497)         self.saved_current_project.append(self.current_project)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 498)         self.current_project = project
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 499) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 500)     def pop_current(self):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 501)         self.current_project = self.saved_current_project[-1]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 502)         del self.saved_current_project[-1]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 503) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 504)     def attributes(self, project):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 505)         """Returns the project-attribute instance for the
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 506)         specified jamfile module."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 507)         return self.module2attributes[project]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 508) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 509)     def attribute(self, project, attribute):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 510)         """Returns the value of the specified attribute in the
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 511)         specified jamfile module."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 512)         return self.module2attributes[project].get(attribute)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 513) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 514)     def target(self, project_module):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 515)         """Returns the project target corresponding to the 'project-module'."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 516)         if not self.module2target[project_module]:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 517)             self.module2target[project_module] = \
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 518)                 ProjectTarget(project_module, project_module,
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 519)                               self.attribute(project_module, "requirements"))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 520)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 521)         return self.module2target[project_module]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 522) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 523)     def use(self, id, location):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 524)         # Use/load a project.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 525)         saved_project = self.current_project
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 526)         project_module = self.load(location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 527)         declared_id = self.attribute(project_module, "id")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 528) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 529)         if not declared_id or declared_id != id:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 530)             # The project at 'location' either have no id or
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 531)             # that id is not equal to the 'id' parameter.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 532)             if self.id2module[id] and self.id2module[id] != project_module:
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 533)                 self.manager.errors()(
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 534) """Attempt to redeclare already existing project id '%s'""" % id)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 535)             self.id2module[id] = project_module
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 536) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 537)         self.current_module = saved_project
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 538) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 539)     def add_rule(self, name, callable):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 540)         """Makes rule 'name' available to all subsequently loaded Jamfiles.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 541) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 542)         Calling that rule wil relay to 'callable'."""
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 543)         self.project_rules_.add_rule(name, callable)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 544) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 545)     def project_rules(self):
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 546)         return self.project_rules_
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 547) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 548)     def glob_internal(self, project, wildcards, excludes, rule_name):
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 549)         location = project.get("source-location")
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 550) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 551)         result = []
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 552)         callable = b2.util.path.__dict__[rule_name]
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 553)         
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 554)         paths = callable(location, wildcards, excludes)
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 555)         has_dir = 0
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 556)         for w in wildcards:
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 557)             if os.path.dirname(w):
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 558)                 has_dir = 1
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 559)                 break
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 560) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 561)         if has_dir or rule_name != "glob":
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 562)             # The paths we've found are relative to current directory,
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 563)             # but the names specified in sources list are assumed to
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 564)             # be relative to source directory of the corresponding
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 565)             # prject. So, just make the name absolute.
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 566)             result = [os.path.join(os.getcwd(), p) for p in paths]
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 567)         else:
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 568)             # There were not directory in wildcard, so the files are all
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 569)             # in the source directory of the project. Just drop the
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 570)             # directory, instead of making paths absolute.
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 571)             result = [os.path.basename(p) for p in paths]
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 572)             
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 573)         return result
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 574) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 575)     def load_module(self, name, extra_path=None):
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 576)         """Classic Boost.Build 'modules' are in fact global variables.
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 577)         Therefore, try to find an already loaded Python module called 'name' in sys.modules. 
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 578)         If the module ist not loaded, find it Boost.Build search
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 579)         path and load it.  The new module is not entered in sys.modules.
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 580)         The motivation here is to have disjoint namespace of modules
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 581)         loaded via 'import/using' in Jamfile, and ordinary Python
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 582)         modules. We don't want 'using foo' in Jamfile to load ordinary
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 583)         Python module 'foo' which is going to not work. And we
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 584)         also don't want 'import foo' in regular Python module to
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 585)         accidentally grab module named foo that is internal to
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 586)         Boost.Build and intended to provide interface to Jamfiles."""
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 587) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 588)         existing = self.loaded_tool_modules_.get(name)
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 589)         if existing:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 590)             return existing
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 591) 
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 592)         modules = sys.modules
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 593)         for class_name in modules:
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 594)             if name in class_name:
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 595)                 module = modules[class_name]
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 596)                 self.loaded_tool_modules_[name] = module
53b0faa2 (jhunold       2008-08-10 18:25:50 +0000 597)                 return module
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 598)         
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 599)         path = extra_path
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 600)         if not path:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 601)             path = []
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 602)         path.extend(self.manager.b2.path())
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 603)         location = None
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 604)         for p in path:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 605)             l = os.path.join(p, name + ".py")
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 606)             if os.path.exists(l):
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 607)                 location = l
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 608)                 break
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 609) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 610)         if not location:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 611)             self.manager.errors()("Cannot find module '%s'" % name)
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 612) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 613)         mname = "__build_build_temporary__"
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 614)         file = open(location)
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 615)         try:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 616)             # TODO: this means we'll never make use of .pyc module,
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 617)             # which might be a problem, or not.
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 618)             module = imp.load_module(mname, file, os.path.basename(location),
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 619)                                      (".py", "r", imp.PY_SOURCE))
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 620)             del sys.modules[mname]
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 621)             self.loaded_tool_modules_[name] = module
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 622)             return module
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 623)         finally:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 624)             file.close()
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 625)         
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 626) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 627) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 628) # FIXME:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 629) # Defines a Boost.Build extension project. Such extensions usually
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 630) # contain library targets and features that can be used by many people.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 631) # Even though extensions are really projects, they can be initialize as
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 632) # a module would be with the "using" (project.project-rules.using)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 633) # mechanism.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 634) #rule extension ( id : options * : * )
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 635) #{
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 636) #    # The caller is a standalone module for the extension.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 637) #    local mod = [ CALLER_MODULE ] ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 638) #    
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 639) #    # We need to do the rest within the extension module.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 640) #    module $(mod)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 641) #    {
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 642) #        import path ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 643) #        
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 644) #        # Find the root project.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 645) #        local root-project = [ project.current ] ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 646) #        root-project = [ $(root-project).project-module ] ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 647) #        while
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 648) #            [ project.attribute $(root-project) parent-module ] &&
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 649) #            [ project.attribute $(root-project) parent-module ] != user-config
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 650) #        {
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 651) #            root-project = [ project.attribute $(root-project) parent-module ] ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 652) #        }
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 653) #        
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 654) #        # Create the project data, and bring in the project rules
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 655) #        # into the module.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 656) #        project.initialize $(__name__) :
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 657) #            [ path.join [ project.attribute $(root-project) location ] ext $(1:L) ] ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 658) #        
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 659) #        # Create the project itself, i.e. the attributes.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 660) #        # All extensions are created in the "/ext" project space.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 661) #        project /ext/$(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 662) #        local attributes = [ project.attributes $(__name__) ] ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 663) #        
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 664) #        # Inherit from the root project of whomever is defining us.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 665) #        project.inherit-attributes $(__name__) : $(root-project) ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 666) #        $(attributes).set parent-module : $(root-project) : exact ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 667) #    }
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 668) #}
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 669)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 670) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 671) class ProjectAttributes:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 672)     """Class keeping all the attributes of a project.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 673) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 674)     The standard attributes are 'id', "location", "project-root", "parent"
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 675)     "requirements", "default-build", "source-location" and "projects-to-build".
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 676)     """
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 677)         
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 678)     def __init__(self, manager, location, project_module):
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 679)         self.manager = manager
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 680)         self.location = location
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 681)         self.project_module = project_module
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 682)         self.attributes = {}
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 683)         self.usage_requirements = None
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 684)         
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 685)     def set(self, attribute, specification, exact):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 686)         """Set the named attribute from the specification given by the user.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 687)         The value actually set may be different."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 688) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 689)         if exact:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 690)             self.__dict__[attribute] = specification
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 691)             
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 692)         elif attribute == "requirements":
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 693)             self.requirements = property_set.refine_from_user_input(
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 694)                 self.requirements, specification,
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 695)                 self.project_module, self.location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 696)             
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 697)         elif attribute == "usage-requirements":
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 698)             unconditional = []
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 699)             for p in specification:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 700)                 split = property.split_conditional(p)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 701)                 if split:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 702)                     unconditional.append(split[1])
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 703)                 else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 704)                     unconditional.append(p)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 705) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 706)             non_free = property.remove("free", unconditional)
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 707)             if non_free:                
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 708)                 pass
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 709)                 # FIXME:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 710)                 #errors.error "usage-requirements" $(specification) "have non-free properties" $(non-free) ;
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 711) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 712)             t = property.translate_paths(specification, self.location)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 713) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 714)             existing = self.__dict__.get("usage-requirements")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 715)             if existing:
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 716)                 new = property_set.create(existing.raw() +  t)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 717)             else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 718)                 new = property_set.create(t)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 719)             self.__dict__["usage-requirements"] = new
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 720) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 721)                 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 722)         elif attribute == "default-build":
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 723)             self.__dict__["default-build"] = property_set.create(specification)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 724)             
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 725)         elif attribute == "source-location":
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 726)             source_location = []
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 727)             for path in specification:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 728)                 source_location += os.path.join(self.location, path)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 729)             self.__dict__["source-location"] = source_location
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 730)                 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 731)         elif attribute == "build-dir":
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 732)             self.__dict__["build-dir"] = os.path.join(self.location, specification)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 733)                  
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 734)         elif not attribute in ["id", "default-build", "location",
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 735)                                "source-location", "parent",
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 736)                                "projects-to-build", "project-root"]:
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 737)             self.manager.errors()(
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 738) """Invalid project attribute '%s' specified
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 739) for project at '%s'""" % (attribute, self.location))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 740)         else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 741)             self.__dict__[attribute] = specification
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 742) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 743)     def get(self, attribute):
cde6f09a (vladimir_prus 2007-10-19 23:12:33 +0000 744)         return self.__dict__[attribute]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 745) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 746)     def dump(self):
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 747)         """Prints the project attributes."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 748)         id = self.get("id")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 749)         if not id:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 750)             id = "(none)"
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 751)         else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 752)             id = id[0]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 753) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 754)         parent = self.get("parent")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 755)         if not parent:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 756)             parent = "(none)"
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 757)         else:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 758)             parent = parent[0]
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 759) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 760)         print "'%s'" % id
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 761)         print "Parent project:%s", parent
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 762)         print "Requirements:%s", self.get("requirements")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 763)         print "Default build:%s", string.join(self.get("debuild-build"))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 764)         print "Source location:%s", string.join(self.get("source-location"))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 765)         print "Projects to build:%s", string.join(self.get("projects-to-build").sort());
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 766) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 767) class ProjectRules:
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 768)     """Class keeping all rules that are made available to Jamfile."""
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 769) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 770)     def __init__(self, registry):
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 771)         self.registry = registry
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 772)         self.manager_ = registry.manager
38d984eb (vladimir_prus 2007-10-13 17:52:25 +0000 773)         self.rules = {}
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 774)         self.local_names = [x for x in self.__class__.__dict__
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 775)                             if x not in ["__init__", "init_project", "add_rule",
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 776)                                          "error_reporting_wrapper", "add_rule_for_type"]]
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 777)         self.all_names_ = [x for x in self.local_names]
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 778) 
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 779)     def add_rule_for_type(self, type):
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 780)         rule_name = type.lower();
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 781) 
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 782)         def xpto (name, sources, requirements = [], default_build = None, usage_requirements = []):
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 783)             return self.manager_.targets().create_typed_target(
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 784)                 type, self.registry.current(), name[0], sources,
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 785)                 requirements, default_build, usage_requirements) 
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 786) 
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 787)         self.add_rule(type.lower(), xpto)
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 788)     
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 789)     def add_rule(self, name, callable):
38d984eb (vladimir_prus 2007-10-13 17:52:25 +0000 790)         self.rules[name] = callable
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 791)         self.all_names_.append(name)
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 792) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 793)     def all_names(self):
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 794)         return self.all_names_
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 795) 
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 796)     def call_and_report_errors(self, callable, *args):
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 797)         result = None
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 798)         try:
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 799)             self.manager_.errors().push_jamfile_context()
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 800)             result = callable(*args)
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 801)         except ExceptionWithUserContext, e:
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 802)             e.report()
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 803)         except Exception, e:
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 804)             try:
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 805)                 self.manager_.errors().handle_stray_exception (e)
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 806)             except ExceptionWithUserContext, e:
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 807)                 e.report()
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 808)         finally:                
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 809)             self.manager_.errors().pop_jamfile_context()
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 810)                                         
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 811)         return result
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 812) 
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 813)     def make_wrapper(self, callable):
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 814)         """Given a free-standing function 'callable', return a new
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 815)         callable that will call 'callable' and report all exceptins,
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 816)         using 'call_and_report_errors'."""
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 817)         def wrapper(*args):
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 818)             self.call_and_report_errors(callable, *args)
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 819)         return wrapper
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 820) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 821)     def init_project(self, project_module):
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 822) 
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 823)         for n in self.local_names:            
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 824)             # Using 'getattr' here gives us a bound method,
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 825)             # while using self.__dict__[r] would give unbound one.
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 826)             v = getattr(self, n)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 827)             if callable(v):
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 828)                 if n == "import_":
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 829)                     n = "import"
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 830)                 else:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 831)                     n = string.replace(n, "_", "-")
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 832)                     
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 833)                 bjam.import_rule(project_module, n,
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 834)                                  self.make_wrapper(v))
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 835) 
38d984eb (vladimir_prus 2007-10-13 17:52:25 +0000 836)         for n in self.rules:
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 837)             bjam.import_rule(project_module, n,
0317671e (vladimir_prus 2007-10-28 14:02:06 +0000 838)                              self.make_wrapper(self.rules[n]))
38d984eb (vladimir_prus 2007-10-13 17:52:25 +0000 839) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 840)     def project(self, *args):
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 841) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 842)         jamfile_module = self.registry.current().project_module()
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 843)         attributes = self.registry.attributes(jamfile_module)
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 844)         
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 845)         id = None
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 846)         if args and args[0]:
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 847)             id = args[0][0]
092119e3 (vladimir_prus 2007-10-16 05:45:31 +0000 848)             args = args[1:]
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 849) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 850)         if id:
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 851)             if id[0] != '/':
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 852)                 id = '/' + id
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 853)             self.registry.register_id (id, jamfile_module)
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 854) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 855)         explicit_build_dir = None
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 856)         for a in args:
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 857)             if a:
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 858)                 attributes.set(a[0], a[1:], exact=0)
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 859)                 if a[0] == "build-dir":
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 860)                     explicit_build_dir = a[1]
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 861)         
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 862)         # If '--build-dir' is specified, change the build dir for the project.
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 863)         if self.registry.global_build_dir:
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 864) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 865)             location = attributes.get("location")
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 866)             # Project with empty location is 'standalone' project, like
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 867)             # user-config, or qt.  It has no build dir.
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 868)             # If we try to set build dir for user-config, we'll then
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 869)             # try to inherit it, with either weird, or wrong consequences.
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 870)             if location and location == attributes.get("project-root"):
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 871)                 # This is Jamroot.
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 872)                 if id:
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 873)                     if explicit_build_dir and os.path.isabs(explicit_build_dir):
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 874)                         self.register.manager.errors()(
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 875) """Absolute directory specified via 'build-dir' project attribute
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 876) Don't know how to combine that with the --build-dir option.""")
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 877) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 878)                     rid = id
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 879)                     if rid[0] == '/':
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 880)                         rid = rid[1:]
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 881) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 882)                     p = os.path.join(self.registry.global_build_dir,
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 883)                                      rid, explicit_build_dir)
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 884)                     attributes.set("build-dir", p, exact=1)
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 885)             elif explicit_build_dir:
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 886)                 self.registry.manager.errors()(
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 887) """When --build-dir is specified, the 'build-project'
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 888) attribute is allowed only for top-level 'project' invocations""")
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 889) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 890)     def constant(self, name, value):
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 891)         """Declare and set a project global constant.
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 892)         Project global constants are normal variables but should
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 893)         not be changed. They are applied to every child Jamfile."""
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 894)         m = "Jamfile</home/ghost/Work/Boost/boost-svn/tools/build/v2_python/python/tests/bjam/make>"
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 895)         self.registry.current().add_constant(name[0], value)
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 896) 
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 897)     def path_constant(self, name, value):
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 898)         """Declare and set a project global constant, whose value is a path. The
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 899)         path is adjusted to be relative to the invocation directory. The given
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 900)         value path is taken to be either absolute, or relative to this project
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 901)         root."""
0ed8e16d (vladimir_prus 2007-10-13 21:34:05 +0000 902)         self.registry.current().add_constant(name[0], value, path=1)
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 903) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 904)     def use_project(self, id, where):
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 905)         # See comment in 'load' for explanation why we record the
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 906)         # parameters as opposed to loading the project now.
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 907)         m = self.registry.current().project_module();
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 908)         self.registry.used_projects[m].append((id, where))
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 909)         
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 910)     def build_project(self, dir):
1674e2d9 (jhunold       2008-08-08 19:52:05 +0000 911)         assert(isinstance(dir, list))
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 912)         jamfile_module = self.registry.current().project_module()
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 913)         attributes = self.registry.attributes(jamfile_module)
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 914)         now = attributes.get("projects-to-build")
1674e2d9 (jhunold       2008-08-08 19:52:05 +0000 915)         attributes.set("projects-to-build", now + dir, exact=True)
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 916) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 917)     def explicit(self, target_names):
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 918)         t = self.registry.current()
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 919)         for n in target_names:
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 920)             t.mark_target_as_explicit(n)
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 921) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 922)     def glob(self, wildcards, excludes=None):
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 923)         return self.registry.glob_internal(self.registry.current(),
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 924)                                            wildcards, excludes, "glob")
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 925) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 926)     def glob_tree(self, wildcards, excludes=None):
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 927)         bad = 0
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 928)         for p in wildcards:
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 929)             if os.path.dirname(p):
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 930)                 bad = 1
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 931) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 932)         if excludes:
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 933)             for p in excludes:
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 934)                 if os.path.dirname(p):
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 935)                     bad = 1
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 936) 
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 937)         if bad:
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 938)             self.registry.manager().errors()(
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 939) "The patterns to 'glob-tree' may not include directory")
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 940)         return self.registry.glob_internal(self.registry.current(),
2a36874b (vladimir_prus 2007-10-14 07:20:55 +0000 941)                                            wildcards, excludes, "glob_tree")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 942)     
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 943) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 944)     def using(self, toolset, *args):
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 945)         # The module referred by 'using' can be placed in
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 946)         # the same directory as Jamfile, and the user
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 947)         # will expect the module to be found even though
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 948)         # the directory is not in BOOST_BUILD_PATH.
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 949)         # So temporary change the search path.
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 950)         jamfile_module = self.registry.current().project_module()
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 951)         attributes = self.registry.attributes(jamfile_module)
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 952)         location = attributes.get("location")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 953) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 954)         m = self.registry.load_module(toolset[0], [location])
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 955)         if not m.__dict__.has_key("init"):
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 956)             self.registry.manager.errors()(
7da7f9c1 (vladimir_prus 2008-05-18 04:29:53 +0000 957)                 "Tool module '%s' does not define the 'init' method" % toolset[0])
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 958)         m.init(*args)
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 959) 
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 960) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 961)     def import_(self, name, names_to_import=None, local_names=None):
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 962) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 963)         name = name[0]
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 964)         jamfile_module = self.registry.current().project_module()
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 965)         attributes = self.registry.attributes(jamfile_module)
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 966)         location = attributes.get("location")
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 967) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 968)         m = self.registry.load_module(name, [location])
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 969) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 970)         for f in m.__dict__:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 971)             v = m.__dict__[f]
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 972)             if callable(v):
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 973)                 bjam.import_rule(jamfile_module, name + "." + f, v)
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 974) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 975)         if names_to_import:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 976)             if not local_names:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 977)                 local_names = names_to_import
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 978) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 979)             if len(names_to_import) != len(local_names):
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 980)                 self.registry.manager.errors()(
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 981) """The number of names to import and local names do not match.""")
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 982) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 983)             for n, l in zip(names_to_import, local_names):
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 984)                 bjam.import_rule(jamfile_module, l, m.__dict__[n])
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 985)         
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 986)     def conditional(self, condition, requirements):
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 987)         """Calculates conditional requirements for multiple requirements
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 988)         at once. This is a shorthand to be reduce duplication and to
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 989)         keep an inline declarative syntax. For example:
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 990) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 991)             lib x : x.cpp : [ conditional <toolset>gcc <variant>debug :
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 992)                 <define>DEBUG_EXCEPTION <define>DEBUG_TRACE ] ;
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 993)         """
f049766b (vladimir_prus 2007-10-10 09:31:06 +0000 994) 
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 995)         c = string.join(condition, ",")
f2aef897 (vladimir_prus 2007-10-14 09:19:52 +0000 996)         return [c + ":" + r for r in requirements]