]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/build/engine.py
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / tools / build / src / build / engine.py
1 # Copyright Pedro Ferreira 2005.
2 # Copyright Vladimir Prus 2007.
3 # Distributed under the Boost
4 # Software License, Version 1.0. (See accompanying
5 # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 bjam_interface = __import__('bjam')
8
9 import operator
10 import re
11
12 import b2.build.property_set as property_set
13
14 from b2.util import set_jam_action, is_iterable
15
16 class BjamAction(object):
17 """Class representing bjam action defined from Python."""
18
19 def __init__(self, action_name, function, has_command=False):
20 assert isinstance(action_name, basestring)
21 assert callable(function) or function is None
22 self.action_name = action_name
23 self.function = function
24 self.has_command = has_command
25
26 def __call__(self, targets, sources, property_set_):
27 assert is_iterable(targets)
28 assert is_iterable(sources)
29 assert isinstance(property_set_, property_set.PropertySet)
30 if self.has_command:
31 # Bjam actions defined from Python have only the command
32 # to execute, and no associated jam procedural code. So
33 # passing 'property_set' to it is not necessary.
34 bjam_interface.call("set-update-action", self.action_name,
35 targets, sources, [])
36 if self.function:
37 self.function(targets, sources, property_set_)
38
39 class BjamNativeAction(BjamAction):
40 """Class representing bjam action defined by Jam code.
41
42 We still allow to associate a Python callable that will
43 be called when this action is installed on any target.
44 """
45
46 def __call__(self, targets, sources, property_set_):
47 assert is_iterable(targets)
48 assert is_iterable(sources)
49 assert isinstance(property_set_, property_set.PropertySet)
50 if self.function:
51 self.function(targets, sources, property_set_)
52
53 p = []
54 if property_set:
55 p = property_set_.raw()
56
57 set_jam_action(self.action_name, targets, sources, p)
58
59 action_modifiers = {"updated": 0x01,
60 "together": 0x02,
61 "ignore": 0x04,
62 "quietly": 0x08,
63 "piecemeal": 0x10,
64 "existing": 0x20}
65
66 class Engine:
67 """ The abstract interface to a build engine.
68
69 For now, the naming of targets, and special handling of some
70 target variables like SEARCH and LOCATE make this class coupled
71 to bjam engine.
72 """
73 def __init__ (self):
74 self.actions = {}
75
76 def add_dependency (self, targets, sources):
77 """Adds a dependency from 'targets' to 'sources'
78
79 Both 'targets' and 'sources' can be either list
80 of target names, or a single target name.
81 """
82 if isinstance (targets, str):
83 targets = [targets]
84 if isinstance (sources, str):
85 sources = [sources]
86 assert is_iterable(targets)
87 assert is_iterable(sources)
88
89 for target in targets:
90 for source in sources:
91 self.do_add_dependency (target, source)
92
93 def get_target_variable(self, targets, variable):
94 """Gets the value of `variable` on set on the first target in `targets`.
95
96 Args:
97 targets (str or list): one or more targets to get the variable from.
98 variable (str): the name of the variable
99
100 Returns:
101 the value of `variable` set on `targets` (list)
102
103 Example:
104
105 >>> ENGINE = get_manager().engine()
106 >>> ENGINE.set_target_variable(targets, 'MY-VAR', 'Hello World')
107 >>> ENGINE.get_target_variable(targets, 'MY-VAR')
108 ['Hello World']
109
110 Equivalent Jam code:
111
112 MY-VAR on $(targets) = "Hello World" ;
113 echo [ on $(targets) return $(MY-VAR) ] ;
114 "Hello World"
115 """
116 if isinstance(targets, str):
117 targets = [targets]
118 assert is_iterable(targets)
119 assert isinstance(variable, basestring)
120
121 return bjam_interface.call('get-target-variable', targets, variable)
122
123 def set_target_variable (self, targets, variable, value, append=0):
124 """ Sets a target variable.
125
126 The 'variable' will be available to bjam when it decides
127 where to generate targets, and will also be available to
128 updating rule for that 'taret'.
129 """
130 if isinstance (targets, str):
131 targets = [targets]
132 if isinstance(value, str):
133 value = [value]
134
135 assert is_iterable(targets)
136 assert isinstance(variable, basestring)
137 assert is_iterable(value)
138
139 if targets:
140 if append:
141 bjam_interface.call("set-target-variable", targets, variable, value, "true")
142 else:
143 bjam_interface.call("set-target-variable", targets, variable, value)
144
145 def set_update_action (self, action_name, targets, sources, properties=None):
146 """ Binds a target to the corresponding update action.
147 If target needs to be updated, the action registered
148 with action_name will be used.
149 The 'action_name' must be previously registered by
150 either 'register_action' or 'register_bjam_action'
151 method.
152 """
153 if isinstance(targets, str):
154 targets = [targets]
155 if isinstance(sources, str):
156 sources = [sources]
157 if properties is None:
158 properties = property_set.empty()
159 assert isinstance(action_name, basestring)
160 assert is_iterable(targets)
161 assert is_iterable(sources)
162 assert(isinstance(properties, property_set.PropertySet))
163
164 self.do_set_update_action (action_name, targets, sources, properties)
165
166 def register_action (self, action_name, command='', bound_list = [], flags = [],
167 function = None):
168 """Creates a new build engine action.
169
170 Creates on bjam side an action named 'action_name', with
171 'command' as the command to be executed, 'bound_variables'
172 naming the list of variables bound when the command is executed
173 and specified flag.
174 If 'function' is not None, it should be a callable taking three
175 parameters:
176 - targets
177 - sources
178 - instance of the property_set class
179 This function will be called by set_update_action, and can
180 set additional target variables.
181 """
182 assert isinstance(action_name, basestring)
183 assert isinstance(command, basestring)
184 assert is_iterable(bound_list)
185 assert is_iterable(flags)
186 assert function is None or callable(function)
187
188 bjam_flags = reduce(operator.or_,
189 (action_modifiers[flag] for flag in flags), 0)
190
191 # We allow command to be empty so that we can define 'action' as pure
192 # python function that would do some conditional logic and then relay
193 # to other actions.
194 assert command or function
195 if command:
196 bjam_interface.define_action(action_name, command, bound_list, bjam_flags)
197
198 self.actions[action_name] = BjamAction(
199 action_name, function, has_command=bool(command))
200
201 def register_bjam_action (self, action_name, function=None):
202 """Informs self that 'action_name' is declared in bjam.
203
204 From this point, 'action_name' is a valid argument to the
205 set_update_action method. The action_name should be callable
206 in the global module of bjam.
207 """
208
209 # We allow duplicate calls to this rule for the same
210 # action name. This way, jamfile rules that take action names
211 # can just register them without specially checking if
212 # action is already registered.
213 assert isinstance(action_name, basestring)
214 assert function is None or callable(function)
215 if action_name not in self.actions:
216 self.actions[action_name] = BjamNativeAction(action_name, function)
217
218 # Overridables
219
220
221 def do_set_update_action (self, action_name, targets, sources, property_set_):
222 assert isinstance(action_name, basestring)
223 assert is_iterable(targets)
224 assert is_iterable(sources)
225 assert isinstance(property_set_, property_set.PropertySet)
226 action = self.actions.get(action_name)
227 if not action:
228 raise Exception("No action %s was registered" % action_name)
229 action(targets, sources, property_set_)
230
231 def do_set_target_variable (self, target, variable, value, append):
232 assert isinstance(target, basestring)
233 assert isinstance(variable, basestring)
234 assert is_iterable(value)
235 assert isinstance(append, int) # matches bools
236 if append:
237 bjam_interface.call("set-target-variable", target, variable, value, "true")
238 else:
239 bjam_interface.call("set-target-variable", target, variable, value)
240
241 def do_add_dependency (self, target, source):
242 assert isinstance(target, basestring)
243 assert isinstance(source, basestring)
244 bjam_interface.call("DEPENDS", target, source)
245
246