]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/src/build/configure.jam
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / tools / build / src / build / configure.jam
CommitLineData
7c673cae 1# Copyright (c) 2010 Vladimir Prus.
b32b8144 2# Copyright 2017 Rene Rivera.
7c673cae
FG
3#
4# Use, modification and distribution is subject to the Boost Software
5# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
6# http://www.boost.org/LICENSE_1_0.txt)
7
8# This module defines function to help with two main tasks:
9#
10# - Discovering build-time configuration for the purposes of adjusting the build
11# process.
12# - Reporting what is built, and how it is configured.
13
14import "class" : new ;
15import common ;
92f5a8d4 16import indirect ;
7c673cae 17import path ;
92f5a8d4 18import project ;
7c673cae
FG
19import property ;
20import property-set ;
21import targets ;
22import config-cache ;
b32b8144
FG
23import feature ;
24import modules ;
11fdf7f2 25import sequence ;
b32b8144 26import utility ;
11fdf7f2 27import virtual-target ;
b32b8144
FG
28
29
30# The configure feature allows external definition of what features are
31# relevant for doing configuration builds. One can add additional relevant
32# features by using:
33#
34# import feature ;
35# import configure ;
36# feature.compose <configure> : <threading> ;
37#
38feature.feature configure : : composite optional ;
39
40# This is the initial set of relevant features. Note that subfeature of all
41# relevant features are also considered relevant.
42#
43feature.compose <configure> :
44 <target-os> <toolset> <address-model> <architecture> <cxxstd> ;
7c673cae
FG
45
46
47rule log-summary ( )
48{
49}
50
51
52.width = 30 ;
53
54rule set-width ( width )
55{
56 .width = $(width) ;
57}
58
59
60# Declare that the components specified by the parameter exist.
61#
62rule register-components ( components * )
63{
64 .components += $(components) ;
65}
66
67
68# Declare that the components specified by the parameters will be built.
69#
70rule components-building ( components * )
71{
72 .built-components += $(components) ;
73}
74
75
76# Report something about component configuration that the user should better
77# know.
78#
79rule log-component-configuration ( component : message )
80{
81 # FIXME: Implement per-property-set logs.
82 .component-logs.$(component) += $(message) ;
83}
84
85
86rule log-check-result ( result )
87{
88 if ! $(.announced-checks)
89 {
90 ECHO "Performing configuration checks\n" ;
91 .announced-checks = 1 ;
92 }
93
94 ECHO $(result) ;
95 # FIXME: Unfinished code. Nothing seems to set .check-results at the moment.
96 #.check-results += $(result) ;
97}
98
99
100rule log-library-search-result ( library : result )
101{
102 local x = [ PAD " - $(library)" : $(.width) ] ;
103 log-check-result "$(x) : $(result)" ;
104}
105
106
107rule print-component-configuration ( )
108{
109 # FIXME: See what was intended with this initial assignment.
110 # local c = [ sequence.unique $(.components) ] ;
111
112 ECHO "\nComponent configuration:\n" ;
113 local c ;
114 for c in $(.components)
115 {
116 local s ;
117 if $(c) in $(.built-components)
118 {
119 s = "building" ;
120 }
121 else
122 {
123 s = "not building" ;
124 }
125 ECHO [ PAD " - $(c)" : $(.width) ] ": $(s)" ;
126 for local m in $(.component-logs.$(c))
127 {
128 ECHO " -" $(m) ;
129 }
130 }
131 ECHO ;
132}
133
134
135rule print-configure-checks-summary ( )
136{
137 # FIXME: The problem with this approach is that the user sees the checks
138 # summary when all checks are done, and has no progress reporting while the
139 # checks are being executed.
140 if $(.check-results)
141 {
142 ECHO "Configuration checks summary\n" ;
143 for local r in $(.check-results)
144 {
145 ECHO $(r) ;
146 }
147 ECHO ;
148 }
149}
150
11fdf7f2
TL
151if --reconfigure in [ modules.peek : ARGV ]
152{
153 .reconfigure = true ;
154}
155
156# Handle the --reconfigure option
157rule maybe-force-rebuild ( targets * )
158{
159 if $(.reconfigure)
160 {
161 local all-targets ;
162 for local t in $(targets)
163 {
164 all-targets += [ virtual-target.traverse $(t) ] ;
165 }
166 for local t in [ sequence.unique $(all-targets) ]
167 {
168 $(t).always ;
169 }
170 }
171}
172
7c673cae
FG
173# Attempts to build a set of virtual targets
174rule try-build ( targets * : ps : what : retry ? )
175{
176 local cache-name = $(what) [ $(ps).raw ] ;
177 cache-name = $(cache-name:J=-) ;
178 local value = [ config-cache.get $(cache-name) ] ;
179
180 local result ;
181 local jam-targets ;
182
11fdf7f2
TL
183 maybe-force-rebuild $(targets) ;
184
7c673cae
FG
185 for local t in $(targets)
186 {
187 jam-targets += [ $(t).actualize ] ;
188 }
189
190 if $(value)
191 {
192 local x = [ PAD " - $(what)" : $(.width) ] ;
193 if $(value) = true
194 {
195 .$(what)-supported.$(ps) = yes ;
196 result = true ;
197 log-check-result "$(x) : yes (cached)" ;
198 }
199 else
200 {
201 log-check-result "$(x) : no (cached)" ;
202 }
203 }
204 else if ! UPDATE_NOW in [ RULENAMES ]
205 {
92f5a8d4 206 # Cannot determine. Assume existence.
7c673cae
FG
207 }
208 else
209 {
210 local x = [ PAD " - $(what)" : $(.width) ] ;
211 if [ UPDATE_NOW $(jam-targets) :
212 $(.log-fd) : ignore-minus-n : ignore-minus-q ]
213 {
214 .$(what)-supported.$(ps) = yes ;
215 result = true ;
216 log-check-result "$(x) : yes" ;
217 }
218 else
219 {
220 log-check-result "$(x) : no" ;
221 }
222 }
223 if ! $(value)
224 {
225 if $(result)
226 {
227 config-cache.set $(cache-name) : true ;
228 }
229 else
230 {
231 config-cache.set $(cache-name) : false ;
232 }
233 }
234 return $(result) ;
235}
236
11fdf7f2
TL
237# Attempts to build several sets of virtual targets. Returns the
238# the index of the first set that builds.
239rule try-find-build ( ps : what : * )
240{
241 local args = 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ;
242 # The outer layer only needs to check $(what), but we
243 # also need to check the individual elements, in case
244 # the set of targets has changed since the last build.
245 local cache-name = $(what) $($(args)[1]) [ $(ps).raw ] ;
246 cache-name = $(cache-name:J=-) ;
247 local value = [ config-cache.get $(cache-name) ] ;
248
249 local result ;
250 local jam-targets ;
251
252 maybe-force-rebuild $($(args)[2-]) ;
253
254 # Make sure that the targets are always actualized,
255 # even if the result is cached. This is needed to
256 # allow clean-all to find them and also to avoid
257 # unintentional behavior changes.
258 for local t in $($(args)[2-])
259 {
260 $(t).actualize ;
261 }
262
263 if $(value)
264 {
265 local none = none ; # What to show when the argument
266 local name = $(value) ;
267 if $(name) != none
268 {
269 name = [ CALC $(name) + 2 ] ;
270 }
271 local x = [ PAD " - $(what)" : $(.width) ] ;
272 local y = [ PAD $($(name)[1]) : 3 ] ;
273 result = $(value) ;
274 log-check-result "$(x) : $(y) (cached)" ;
275 }
276 else
277 {
278 local x = [ PAD " - $(what)" : $(.width) ] ;
279 for local i in $(args)
280 {
281 if ! $($(i)[1])
282 {
283 break ;
284 }
285 local jam-targets ;
286 for local t in $($(i)[2-])
287 {
288 jam-targets += [ $(t).actualize ] ;
289 }
290 if [ UPDATE_NOW $(jam-targets) :
291 $(.log-fd) : ignore-minus-n : ignore-minus-q ]
292 {
293 result = [ CALC $(i) - 2 ] ;
294 log-check-result "$(x) : $($(i)[1])" ;
295 break ;
296 }
297 }
298 if ! $(result)
299 {
300 log-check-result "$(x) : none" ;
301 result = none ;
302 }
303 }
304 if ! $(value)
305 {
306 if $(result)
307 {
308 config-cache.set $(cache-name) : $(result) ;
309 }
310 else
311 {
312 config-cache.set $(cache-name) : $(result) ;
313 }
314 }
315 if $(result) != none
316 {
317 return $(result) ;
318 }
319}
320
7c673cae
FG
321# Attempt to build a metatarget named by 'metatarget-reference'
322# in context of 'project' with properties 'ps'.
323# Returns non-empty value if build is OK.
324rule builds-raw ( metatarget-reference : project : ps : what : retry ? )
325{
326 local result ;
327
328 if ! $(retry) && ! $(.$(what)-tested.$(ps))
329 {
330 .$(what)-tested.$(ps) = true ;
331
332 local targets = [ targets.generate-from-reference
333 $(metatarget-reference) : $(project) : $(ps) ] ;
334
335 result = [ try-build $(targets[2-]) : $(ps) : $(what) : $(retry) ] ;
336 .$(what)-supported.$(ps) = $(result) ;
337
338 return $(result) ;
339
340 }
341 else
342 {
343 return $(.$(what)-supported.$(ps)) ;
344 }
345}
346
11fdf7f2
TL
347# Attempt to build a metatarget named by 'metatarget-reference'
348# in context of 'project' with properties 'ps'.
349# Returns the 1-based index of the first target
350# that builds.
351rule find-builds-raw ( project : ps : what : * )
352{
353 local result ;
354 local args = 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ;
355
356 if ! $(.$(what)-tested.$(ps))
357 {
358 .$(what)-tested.$(ps) = true ;
359 local targets.$(i) what.$(i) ;
360 for local i in $(args)
361 {
362 if ! $($(i))
363 {
364 break ;
365 }
366 targets.$(i) = [ targets.generate-from-reference
367 $($(i)[1]) : $(project) : $(ps) ] ;
368 # ignore usage requirements
369 targets.$(i) = $(targets.$(i)[2-]) ;
370 if $($(i)[2])
371 {
372 what.$(i) = $($(i)[2]) ;
373 }
374 else
375 {
376 local t = [ targets.resolve-reference
377 $($(i)[1]) : $(project) ] ;
378 what.$(i) = [ $(t[1]).name ] ;
379 }
380 }
381
382 result = [ try-find-build $(ps) : $(what)
383 : $(what.4) $(targets.4)
384 : $(what.5) $(targets.5)
385 : $(what.6) $(targets.6)
386 : $(what.7) $(targets.7)
387 : $(what.8) $(targets.8)
388 : $(what.9) $(targets.9)
389 : $(what.10) $(targets.10)
390 : $(what.11) $(targets.11)
391 : $(what.12) $(targets.12)
392 : $(what.13) $(targets.13)
393 : $(what.14) $(targets.14)
394 : $(what.15) $(targets.15)
395 : $(what.16) $(targets.16)
396 : $(what.17) $(targets.17)
397 : $(what.18) $(targets.18)
398 : $(what.19) $(targets.19) ] ;
399 .$(what)-result.$(ps) = $(result) ;
400
401 return $(result) ;
402 }
403 else
404 {
405 return $(.$(what)-result.$(ps)) ;
406 }
407}
408
409rule get-relevant-features ( )
b32b8144
FG
410{
411 local relevant = [ feature.expand <configure> ] ;
412 local result = ;
413 for local f in $(relevant)
414 {
415 if $(f) != <configure>
416 {
417 local sub = [ modules.peek feature : $(f).subfeatures ] ;
418 local name = [ utility.ungrist $(f) ] ;
419 result += $(f) <$(name)-$(sub)> ;
420 }
421 }
422 return $(result) ;
423}
424
7c673cae
FG
425rule builds ( metatarget-reference : properties * : what ? : retry ? )
426{
b32b8144
FG
427 local toolset-subfeatures = [ modules.peek feature : <toolset>.subfeatures ] ;
428 toolset-subfeatures = <toolset-$(toolset-subfeatures)> ;
7c673cae
FG
429 # FIXME: This should not be hardcoded. Other checks might want to consider a
430 # different set of features as relevant.
b32b8144 431 local relevant = [ property.select [ get-relevant-features ] : $(properties) ] ;
7c673cae
FG
432 local ps = [ property-set.create $(relevant) ] ;
433 local t = [ targets.current ] ;
434 local p = [ $(t).project ] ;
435
436 if ! $(what)
437 {
438 local resolved = [ targets.resolve-reference $(metatarget-reference) : $(p) ] ;
439 local name = [ $(resolved[1]).name ] ;
440 what = "$(name) builds" ;
441 }
442
443 return [ builds-raw $(metatarget-reference) : $(p) : $(ps) : $(what) :
444 $(retry) ] ;
445}
446
11fdf7f2
TL
447rule find-builds ( what : properties * : * )
448{
449 local relevant = [ property.select [ get-relevant-features ] : $(properties) ] ;
450 local ps = [ property-set.create $(relevant) ] ;
451 local t = [ targets.current ] ;
452 local p = [ $(t).project ] ;
453
454 return [ find-builds-raw $(p) : $(ps) : $(what) :
455 $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) :
456 $(10) : $(11) : $(12) : $(13) : $(14) : $(15) :
457 $(16) : $(17) : $(18) : $(19) ] ;
458}
459
7c673cae
FG
460
461# Called by Boost.Build startup code to specify the file to receive the
462# configuration check results. Should never be called by user code.
463#
464rule set-log-file ( log-file )
465{
466 path.makedirs [ path.parent $(log-file) ] ;
11fdf7f2
TL
467 .log-fd = [ FILE_OPEN [ path.native $(log-file) ] : "w" ] ;
468 if ! $(.log-fd)
469 {
470 ECHO "warning:" failed to open log file $(log-file) for writing ;
471 }
7c673cae
FG
472}
473
474
475# Frontend rules
476
477class check-target-builds-worker
478{
479 import configure ;
480 import property-set ;
481 import targets ;
92f5a8d4 482 import project ;
7c673cae
FG
483 import property ;
484
485 rule __init__ ( target message ? : true-properties * : false-properties * )
486 {
92f5a8d4 487 local project = [ project.current ] ;
7c673cae
FG
488 self.target = $(target) ;
489 self.message = $(message) ;
92f5a8d4
TL
490 self.true-properties =
491 [ configure.translate-properties $(true-properties) : $(project) ] ;
492 self.false-properties =
493 [ configure.translate-properties $(false-properties) : $(project) ] ;
7c673cae
FG
494 }
495
496 rule check ( properties * )
497 {
498 local choosen ;
499 if [ configure.builds $(self.target) : $(properties) : $(self.message) ]
500 {
501 choosen = $(self.true-properties) ;
502 }
503 else
504 {
505 choosen = $(self.false-properties) ;
506 }
507 return [ property.evaluate-conditionals-in-context $(choosen) :
508 $(properties) ] ;
509 }
510}
511
11fdf7f2
TL
512class configure-choose-worker
513{
514 import configure ;
515 import property ;
92f5a8d4 516 import project ;
11fdf7f2
TL
517 rule __init__ ( message : * )
518 {
92f5a8d4 519 local project = [ project.current ] ;
11fdf7f2
TL
520 self.message = $(message) ;
521 for i in 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
522 {
523 local name = [ CALC $(i) - 1 ] ;
524 self.targets.$(name) = $($(i)[1]) ;
525 if ! $($(i)[2]:G) # Check whether the second argument is a property
526 {
527 self.what.$(name) = $($(i)[2]) ;
528 self.props.$(name) = $($(i)[3-]) ;
529 }
530 else
531 {
532 self.props.$(name) = $($(i)[2-]) ;
533 }
92f5a8d4
TL
534 self.props.$(name) = [ configure.translate-properties
535 $(self.props.$(name)) : $(project) ] ;
11fdf7f2
TL
536 }
537 }
538 rule all-properties ( )
539 {
540 local i = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ;
541 return $(self.props.$(i)) ;
542 }
543 rule check ( properties * )
544 {
545 local i = [ configure.find-builds $(self.message) : $(properties)
546 : $(self.targets.1) $(self.what.1)
547 : $(self.targets.2) $(self.what.2)
548 : $(self.targets.3) $(self.what.3)
549 : $(self.targets.4) $(self.what.4)
550 : $(self.targets.5) $(self.what.5)
551 : $(self.targets.6) $(self.what.6)
552 : $(self.targets.7) $(self.what.7)
553 : $(self.targets.8) $(self.what.8)
554 : $(self.targets.9) $(self.what.9)
555 : $(self.targets.10) $(self.what.10)
556 : $(self.targets.11) $(self.what.11)
557 : $(self.targets.12) $(self.what.12)
558 : $(self.targets.13) $(self.what.13)
559 : $(self.targets.14) $(self.what.14)
560 : $(self.targets.15) $(self.what.15)
561 : $(self.targets.16) $(self.what.16)
562 : $(self.targets.17) $(self.what.17)
563 : $(self.targets.18) $(self.what.18)
564 : $(self.targets.19) $(self.what.19) ] ;
565 if $(self.props.$(i))
566 {
567 return [ property.evaluate-conditionals-in-context $(self.props.$(i)) : $(properties) ] ;
568 }
569 }
570}
571
92f5a8d4
TL
572rule translate-properties ( properties * : project ? )
573{
574 if $(project) && [ $(project).location ]
575 {
576 local location = [ $(project).location ] ;
577 local m = [ $(project).project-module ] ;
578 local project-id = [ project.attribute $(m) id ] ;
579 project-id ?= [ path.root $(location) [ path.pwd ] ] ;
580 return [ property.translate $(properties)
581 : $(project-id) : $(location) : $(m) ] ;
582 }
583 else
584 {
585 return $(properties) ;
586 }
587}
7c673cae
FG
588
589rule check-target-builds ( target message ? : true-properties * :
590 false-properties * )
591{
592 local instance = [ new check-target-builds-worker $(target) $(message) :
593 $(true-properties) : $(false-properties) ] ;
92f5a8d4
TL
594 local rulename = [ indirect.make check : $(instance) ] ;
595 return <conditional>@$(rulename)
11fdf7f2
TL
596 [ property.evaluate-conditional-relevance
597 $(true-properties) $(false-properties)
598 : [ configure.get-relevant-features ] ] ;
599}
600
601# Usage:
602# [ configure.choose "architecture"
603# : /config//x86 x86 <architecture>x86
604# : /config//mips mips <architecture>mips
605# ]
606rule choose ( message : * )
607{
608 local instance = [ new configure-choose-worker $(message)
609 : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9)
610 : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16)
611 : $(17) : $(18) : $(19) ] ;
92f5a8d4
TL
612 local rulename = [ indirect.make check : $(instance) ] ;
613 return <conditional>@$(rulename)
11fdf7f2
TL
614 [ property.evaluate-conditional-relevance
615 [ $(instance).all-properties ]
616 : [ configure.get-relevant-features ] ] ;
7c673cae
FG
617}
618
619
620IMPORT $(__name__) : check-target-builds : : check-target-builds ;