]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/build/build_request.py
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / tools / build / src / build / build_request.py
1 # Status: being ported by Vladimir Prus
2 # TODO: need to re-compare with mainline of .jam
3 # Base revision: 40480
4 #
5 # (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and
6 # distribute this software is granted provided this copyright notice appears in
7 # all copies. This software is provided "as is" without express or implied
8 # warranty, and with no claim as to its suitability for any purpose.
9
10 import b2.build.feature
11 feature = b2.build.feature
12
13 from b2.util.utility import *
14 from b2.util import is_iterable_typed
15 import b2.build.property_set as property_set
16
17 def expand_no_defaults (property_sets):
18 """ Expand the given build request by combining all property_sets which don't
19 specify conflicting non-free features.
20 """
21 assert is_iterable_typed(property_sets, property_set.PropertySet)
22 # First make all features and subfeatures explicit
23 expanded_property_sets = [ps.expand_subfeatures() for ps in property_sets]
24
25 # Now combine all of the expanded property_sets
26 product = __x_product (expanded_property_sets)
27
28 return [property_set.create(p) for p in product]
29
30
31 def __x_product (property_sets):
32 """ Return the cross-product of all elements of property_sets, less any
33 that would contain conflicting values for single-valued features.
34 """
35 assert is_iterable_typed(property_sets, property_set.PropertySet)
36 x_product_seen = set()
37 return __x_product_aux (property_sets, x_product_seen)[0]
38
39 def __x_product_aux (property_sets, seen_features):
40 """Returns non-conflicting combinations of property sets.
41
42 property_sets is a list of PropertySet instances. seen_features is a set of Property
43 instances.
44
45 Returns a tuple of:
46 - list of lists of Property instances, such that within each list, no two Property instance
47 have the same feature, and no Property is for feature in seen_features.
48 - set of features we saw in property_sets
49 """
50 assert is_iterable_typed(property_sets, property_set.PropertySet)
51 assert isinstance(seen_features, set)
52 if not property_sets:
53 return ([], set())
54
55 properties = property_sets[0].all()
56
57 these_features = set()
58 for p in property_sets[0].non_free():
59 these_features.add(p.feature)
60
61 # Note: the algorithm as implemented here, as in original Jam code, appears to
62 # detect conflicts based on features, not properties. For example, if command
63 # line build request say:
64 #
65 # <a>1/<b>1 c<1>/<b>1
66 #
67 # It will decide that those two property sets conflict, because they both specify
68 # a value for 'b' and will not try building "<a>1 <c1> <b1>", but rather two
69 # different property sets. This is a topic for future fixing, maybe.
70 if these_features & seen_features:
71
72 (inner_result, inner_seen) = __x_product_aux(property_sets[1:], seen_features)
73 return (inner_result, inner_seen | these_features)
74
75 else:
76
77 result = []
78 (inner_result, inner_seen) = __x_product_aux(property_sets[1:], seen_features | these_features)
79 if inner_result:
80 for inner in inner_result:
81 result.append(properties + inner)
82 else:
83 result.append(properties)
84
85 if inner_seen & these_features:
86 # Some of elements in property_sets[1:] conflict with elements of property_sets[0],
87 # Try again, this time omitting elements of property_sets[0]
88 (inner_result2, inner_seen2) = __x_product_aux(property_sets[1:], seen_features)
89 result.extend(inner_result2)
90
91 return (result, inner_seen | these_features)
92
93
94
95 def looks_like_implicit_value(v):
96 """Returns true if 'v' is either implicit value, or
97 the part before the first '-' symbol is implicit value."""
98 assert isinstance(v, basestring)
99 if feature.is_implicit_value(v):
100 return 1
101 else:
102 split = v.split("-")
103 if feature.is_implicit_value(split[0]):
104 return 1
105
106 return 0
107
108 def from_command_line(command_line):
109 """Takes the command line tokens (such as taken from ARGV rule)
110 and constructs build request from it. Returns a list of two
111 lists. First is the set of targets specified in the command line,
112 and second is the set of requested build properties."""
113 assert is_iterable_typed(command_line, basestring)
114 targets = []
115 properties = []
116
117 for e in command_line:
118 if e[:1] != "-":
119 # Build request spec either has "=" in it, or completely
120 # consists of implicit feature values.
121 if e.find("=") != -1 or looks_like_implicit_value(e.split("/")[0]):
122 properties.append(e)
123 elif e:
124 targets.append(e)
125
126 return [targets, properties]
127
128 # Converts one element of command line build request specification into
129 # internal form.
130 def convert_command_line_element(e):
131 assert isinstance(e, basestring)
132 result = None
133 parts = e.split("/")
134 for p in parts:
135 m = p.split("=")
136 if len(m) > 1:
137 feature = m[0]
138 values = m[1].split(",")
139 lresult = [("<%s>%s" % (feature, v)) for v in values]
140 else:
141 lresult = p.split(",")
142
143 if p.find('-') == -1:
144 # FIXME: first port property.validate
145 # property.validate cannot handle subfeatures,
146 # so we avoid the check here.
147 #for p in lresult:
148 # property.validate(p)
149 pass
150
151 if not result:
152 result = lresult
153 else:
154 result = [e1 + "/" + e2 for e1 in result for e2 in lresult]
155
156 return [property_set.create(b2.build.feature.split(r)) for r in result]
157
158 ###
159 ### rule __test__ ( )
160 ### {
161 ### import assert feature ;
162 ###
163 ### feature.prepare-test build-request-test-temp ;
164 ###
165 ### import build-request ;
166 ### import build-request : expand_no_defaults : build-request.expand_no_defaults ;
167 ### import errors : try catch ;
168 ### import feature : feature subfeature ;
169 ###
170 ### feature toolset : gcc msvc borland : implicit ;
171 ### subfeature toolset gcc : version : 2.95.2 2.95.3 2.95.4
172 ### 3.0 3.0.1 3.0.2 : optional ;
173 ###
174 ### feature variant : debug release : implicit composite ;
175 ### feature inlining : on off ;
176 ### feature "include" : : free ;
177 ###
178 ### feature stdlib : native stlport : implicit ;
179 ###
180 ### feature runtime-link : dynamic static : symmetric ;
181 ###
182 ###
183 ### local r ;
184 ###
185 ### r = [ build-request.from-command-line bjam debug runtime-link=dynamic ] ;
186 ### assert.equal [ $(r).get-at 1 ] : ;
187 ### assert.equal [ $(r).get-at 2 ] : debug <runtime-link>dynamic ;
188 ###
189 ### try ;
190 ### {
191 ###
192 ### build-request.from-command-line bjam gcc/debug runtime-link=dynamic/static ;
193 ### }
194 ### catch \"static\" is not a value of an implicit feature ;
195 ###
196 ###
197 ### r = [ build-request.from-command-line bjam -d2 --debug debug target runtime-link=dynamic ] ;
198 ### assert.equal [ $(r).get-at 1 ] : target ;
199 ### assert.equal [ $(r).get-at 2 ] : debug <runtime-link>dynamic ;
200 ###
201 ### r = [ build-request.from-command-line bjam debug runtime-link=dynamic,static ] ;
202 ### assert.equal [ $(r).get-at 1 ] : ;
203 ### assert.equal [ $(r).get-at 2 ] : debug <runtime-link>dynamic <runtime-link>static ;
204 ###
205 ### r = [ build-request.from-command-line bjam debug gcc/runtime-link=dynamic,static ] ;
206 ### assert.equal [ $(r).get-at 1 ] : ;
207 ### assert.equal [ $(r).get-at 2 ] : debug gcc/<runtime-link>dynamic
208 ### gcc/<runtime-link>static ;
209 ###
210 ### r = [ build-request.from-command-line bjam msvc gcc,borland/runtime-link=static ] ;
211 ### assert.equal [ $(r).get-at 1 ] : ;
212 ### assert.equal [ $(r).get-at 2 ] : msvc gcc/<runtime-link>static
213 ### borland/<runtime-link>static ;
214 ###
215 ### r = [ build-request.from-command-line bjam gcc-3.0 ] ;
216 ### assert.equal [ $(r).get-at 1 ] : ;
217 ### assert.equal [ $(r).get-at 2 ] : gcc-3.0 ;
218 ###
219 ### feature.finish-test build-request-test-temp ;
220 ### }
221 ###
222 ###