]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/build/build-request.jam
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / tools / build / src / build / build-request.jam
1 # Copyright 2002 Dave Abrahams
2 # Distributed under the Boost Software License, Version 1.0.
3 # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4
5 import "class" : new ;
6 import sequence ;
7 import set ;
8 import regex ;
9 import feature ;
10 import property ;
11 import container ;
12 import string ;
13
14
15 # Transform property-set by applying f to each component property.
16 #
17 local rule apply-to-property-set ( f property-set )
18 {
19 local properties = [ feature.split $(property-set) ] ;
20 return [ string.join [ $(f) $(properties) ] : / ] ;
21 }
22
23
24 # Expand the given build request by combining all property-sets which do not
25 # specify conflicting non-free features. Expects all the project files to
26 # already be loaded.
27 #
28 rule expand-no-defaults ( property-sets * )
29 {
30 # First make all features and subfeatures explicit.
31 local expanded-property-sets = [ sequence.transform apply-to-property-set
32 feature.expand-subfeatures : $(property-sets) ] ;
33
34 # Now combine all of the expanded property-sets
35 local product = [ x-product $(expanded-property-sets) : $(feature-space) ] ;
36
37 return $(product) ;
38 }
39
40
41 # Implementation of x-product, below. Expects all the project files to already
42 # be loaded.
43 #
44 local rule x-product-aux ( property-sets + )
45 {
46 local result ;
47 local p = [ feature.split $(property-sets[1]) ] ;
48 local f = [ set.difference $(p:G) : [ feature.free-features ] ] ;
49 local seen ;
50 # No conflict with things used at a higher level?
51 if ! [ set.intersection $(f) : $(x-product-used) ]
52 {
53 local x-product-seen ;
54 {
55 # Do not mix in any conflicting features.
56 local x-product-used = $(x-product-used) $(f) ;
57
58 if $(property-sets[2])
59 {
60 local rest = [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ;
61 result = $(property-sets[1])/$(rest) ;
62 }
63
64 result ?= $(property-sets[1]) ;
65 }
66
67 # If we did not encounter a conflicting feature lower down, do not
68 # recurse again.
69 if ! [ set.intersection $(f) : $(x-product-seen) ]
70 {
71 property-sets = ;
72 }
73
74 seen = $(x-product-seen) ;
75 }
76
77 if $(property-sets[2])
78 {
79 result += [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ;
80 }
81
82 # Note that we have seen these features so that higher levels will recurse
83 # again without them set.
84 x-product-seen += $(f) $(seen) ;
85 return $(result) ;
86 }
87
88
89 # Return the cross-product of all elements of property-sets, less any that would
90 # contain conflicting values for single-valued features. Expects all the project
91 # files to already be loaded.
92 #
93 local rule x-product ( property-sets * )
94 {
95 if $(property-sets).non-empty
96 {
97 # Prepare some "scoped globals" that can be used by the implementation
98 # function, x-product-aux.
99 local x-product-seen x-product-used ;
100 return [ x-product-aux $(property-sets) : $(feature-space) ] ;
101 }
102 # Otherwise return empty.
103 }
104
105
106 # Returns true if either 'v' or the part of 'v' before the first '-' symbol is
107 # an implicit value. Expects all the project files to already be loaded.
108 #
109 local rule looks-like-implicit-value ( v )
110 {
111 if [ feature.is-implicit-value $(v) ]
112 {
113 return true ;
114 }
115 else
116 {
117 local split = [ regex.split $(v) - ] ;
118 if [ feature.is-implicit-value $(split[1]) ]
119 {
120 return true ;
121 }
122 }
123 }
124
125
126 # Takes the command line tokens (such as taken from the ARGV rule) and
127 # constructs a build request from them. Returns a vector of two vectors (where
128 # "vector" means container.jam's "vector"). First is the set of targets
129 # specified in the command line, and second is the set of requested build
130 # properties. Expects all the project files to already be loaded.
131 #
132 rule from-command-line ( command-line * )
133 {
134 local targets ;
135 local properties ;
136
137 command-line = $(command-line[2-]) ;
138 local skip-next = ;
139 for local e in $(command-line)
140 {
141 if $(skip-next)
142 {
143 skip-next = ;
144 }
145 else if ! [ MATCH ^(-) : $(e) ]
146 {
147 # Build request spec either has "=" in it or completely consists of
148 # implicit feature values.
149 local fs = feature-space ;
150 if [ MATCH "(.*=.*)" : $(e) ]
151 || [ looks-like-implicit-value $(e:D=) : $(feature-space) ]
152 {
153 properties += $(e) ;
154 }
155 else if $(e)
156 {
157 targets += $(e) ;
158 }
159 }
160 else if [ MATCH "^(-[-ldjfsto])$" : $(e) ]
161 {
162 skip-next = true ;
163 }
164 }
165 return [ new vector
166 [ new vector $(targets) ]
167 [ new vector $(properties) ] ] ;
168 }
169
170
171 # Converts a list of elements of command line build request specification into internal
172 # form. Expects all the project files to already be loaded.
173 #
174 rule convert-command-line-elements ( elements * )
175 {
176 local result ;
177 for local e in $(elements)
178 {
179 result += [ convert-command-line-element $(e) ] ;
180 }
181 return $(result) ;
182 }
183
184
185 # Converts one element of command line build request specification into internal
186 # form.
187 local rule convert-command-line-element ( e )
188 {
189 local result ;
190 local parts = [ regex.split $(e) "/" ] ;
191 while $(parts)
192 {
193 local p = $(parts[1]) ;
194 local m = [ MATCH "([^=]*)=(.*)" : $(p) ] ;
195 local lresult ;
196 local feature ;
197 local values ;
198 if $(m)
199 {
200 feature = $(m[1]) ;
201 values = [ regex.split $(m[2]) "," ] ;
202 lresult = <$(feature)>$(values) ;
203 }
204 else
205 {
206 lresult = [ regex.split $(p) "," ] ;
207 }
208
209 if $(feature) && free in [ feature.attributes <$(feature)> ]
210 {
211 # If we have free feature, then the value is everything
212 # until the end of the command line token. Slashes in
213 # the following string are not taked to mean separation
214 # of properties. Commas are also not interpreted specially.
215 values = $(values:J=,) ;
216 values = $(values) $(parts[2-]) ;
217 values = $(values:J=/) ;
218 lresult = <$(feature)>$(values) ;
219 parts = ;
220 }
221
222 if ! [ MATCH (.*-.*) : $(p) ]
223 {
224 # property.validate cannot handle subfeatures, so we avoid the check
225 # here.
226 for local p in $(lresult)
227 {
228 property.validate $(p) : $(feature-space) ;
229 }
230 }
231
232 if ! $(result)
233 {
234 result = $(lresult) ;
235 }
236 else
237 {
238 result = $(result)/$(lresult) ;
239 }
240
241 parts = $(parts[2-]) ;
242 }
243
244 return $(result) ;
245 }
246
247
248 rule __test__ ( )
249 {
250 import assert ;
251 import feature ;
252
253 feature.prepare-test build-request-test-temp ;
254
255 import build-request ;
256 import build-request : expand-no-defaults : build-request.expand-no-defaults ;
257 import errors : try catch ;
258 import feature : feature subfeature ;
259
260 feature toolset : gcc msvc borland : implicit ;
261 subfeature toolset gcc : version : 2.95.2 2.95.3 2.95.4
262 3.0 3.0.1 3.0.2 : optional ;
263
264 feature variant : debug release : implicit composite ;
265 feature inlining : on off ;
266 feature "include" : : free ;
267
268 feature stdlib : native stlport : implicit ;
269
270 feature runtime-link : dynamic static : symmetric ;
271
272 # Empty build requests should expand to empty.
273 assert.result
274 : build-request.expand-no-defaults ;
275
276 assert.result
277 <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug
278 <toolset>msvc/<stdlib>stlport/<variant>debug
279 <toolset>msvc/<variant>debug
280 : build-request.expand-no-defaults gcc-3.0.1/stlport msvc/stlport msvc debug ;
281
282 assert.result
283 <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug
284 <toolset>msvc/<variant>debug
285 <variant>debug/<toolset>msvc/<stdlib>stlport
286 : build-request.expand-no-defaults gcc-3.0.1/stlport msvc debug msvc/stlport ;
287
288 assert.result
289 <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug/<inlining>off
290 <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>release/<inlining>off
291 : build-request.expand-no-defaults gcc-3.0.1/stlport debug release <inlining>off ;
292
293 assert.result
294 <include>a/b/c/<toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug/<include>x/y/z
295 <include>a/b/c/<toolset>msvc/<stdlib>stlport/<variant>debug/<include>x/y/z
296 <include>a/b/c/<toolset>msvc/<variant>debug/<include>x/y/z
297 : build-request.expand-no-defaults <include>a/b/c gcc-3.0.1/stlport msvc/stlport msvc debug <include>x/y/z ;
298
299 local r ;
300
301 try ;
302 {
303 r = [ build-request.from-command-line bjam gcc/debug runtime-link=dynamic/static ] ;
304 build-request.convert-command-line-elements [ $(r).get-at 2 ] ;
305 }
306 catch \"static\" is not an implicit feature value ;
307
308 r = [ build-request.from-command-line bjam debug runtime-link=dynamic ] ;
309 assert.equal [ $(r).get-at 1 ] : ;
310 assert.equal [ $(r).get-at 2 ] : debug runtime-link=dynamic ;
311
312 assert.equal
313 [ build-request.convert-command-line-elements debug runtime-link=dynamic ]
314 : debug <runtime-link>dynamic ;
315
316 r = [ build-request.from-command-line bjam -d2 --debug debug target runtime-link=dynamic ] ;
317 assert.equal [ $(r).get-at 1 ] : target ;
318 assert.equal [ $(r).get-at 2 ] : debug runtime-link=dynamic ;
319
320 assert.equal
321 [ build-request.convert-command-line-elements debug runtime-link=dynamic ]
322 : debug <runtime-link>dynamic ;
323
324 r = [ build-request.from-command-line bjam debug runtime-link=dynamic,static ] ;
325 assert.equal [ $(r).get-at 1 ] : ;
326 assert.equal [ $(r).get-at 2 ] : debug runtime-link=dynamic,static ;
327
328 assert.equal
329 [ build-request.convert-command-line-elements debug runtime-link=dynamic,static ]
330 : debug <runtime-link>dynamic <runtime-link>static ;
331
332 r = [ build-request.from-command-line bjam debug gcc/runtime-link=dynamic,static ] ;
333 assert.equal [ $(r).get-at 1 ] : ;
334 assert.equal [ $(r).get-at 2 ] : debug gcc/runtime-link=dynamic,static ;
335
336 assert.equal
337 [ build-request.convert-command-line-elements debug gcc/runtime-link=dynamic,static ]
338 : debug gcc/<runtime-link>dynamic gcc/<runtime-link>static ;
339
340 r = [ build-request.from-command-line bjam msvc gcc,borland/runtime-link=static ] ;
341 assert.equal [ $(r).get-at 1 ] : ;
342 assert.equal [ $(r).get-at 2 ] : msvc gcc,borland/runtime-link=static ;
343
344 assert.equal
345 [ build-request.convert-command-line-elements msvc gcc,borland/runtime-link=static ]
346 : msvc gcc/<runtime-link>static borland/<runtime-link>static ;
347
348 r = [ build-request.from-command-line bjam gcc-3.0 ] ;
349 assert.equal [ $(r).get-at 1 ] : ;
350 assert.equal [ $(r).get-at 2 ] : gcc-3.0 ;
351
352 assert.equal
353 [ build-request.convert-command-line-elements gcc-3.0 ]
354 : gcc-3.0 ;
355
356 feature.finish-test build-request-test-temp ;
357 }