]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/contrib/modular.jam
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / tools / build / src / contrib / modular.jam
1 # Copyright Rene Rivera 2015
2 # Distributed under the Boost Software License, Version 1.0.
3 # (See accompanying file LICENSE_1_0.txt or copy at
4 # http://www.boost.org/LICENSE_1_0.txt)
5
6 import path ;
7 import project ;
8 import modules ;
9 import regex ;
10 import type ;
11
12 # Add a location, i.e. directory, where to search for libraries.
13 # The optional 'prefix' indicates which rooted-prefixes the new
14 # search dir applies to. The prefix defaults to '/'.
15 rule add-location ( dir prefix ? : base-dir ? )
16 {
17 process-args ;
18
19 prefix ?= "/" ;
20
21 # Dir path of caller to base paths from.
22 caller-module ?= [ CALLER_MODULE ] ;
23 local caller-dir = [ modules.peek $(caller-module) : __file__ ] ;
24 caller-dir = $(caller-dir:D) ;
25
26 base-dir ?= $(caller-dir) ;
27
28 .search-path-prefix += $(prefix) ;
29 .search-path.$(prefix) += [ path.root [ path.root $(dir) $(base-dir) ] [ path.pwd ] ] ;
30 }
31
32 # Declares additional definitions of a modular library target external
33 # to the modular library build itself. This makes it possible to externally
34 # define modular libraries without modifying the library. The passed in
35 # values are added on demand when the named library is first declared.
36 rule external (
37 name : sources * : requirements * : default-build * :
38 usage-requirements * )
39 {
40 .external.($(name)).sources = $(sources) ;
41 .external.($(name)).requirements = $(requirements) ;
42 .external.($(name)).default-build = $(default-build) ;
43 .external.($(name)).usage-requirements = $(usage-requirements) ;
44 }
45
46 # Find, and declare, any modular libraries referenced in the target-refs.
47 # This will both load the modular libraries, and declare/manufacture
48 # the modular libraries as needed.
49 rule find ( target-refs + )
50 {
51 process-args ;
52
53 local caller-mod = [ CALLER_MODULE ] ;
54 local caller-dir = [ modules.peek $(caller-mod) : __file__ ] ;
55 caller-dir = $(caller-dir:D) ;
56 caller-dir = [ path.root $(caller-dir) [ path.pwd ] ] ;
57
58 local result-refs ;
59 for local target-ref in $(target-refs)
60 {
61 result-refs += [ resolve-reference $(target-ref)
62 : $(caller-mod) $(caller-dir) ] ;
63 }
64
65 return $(result-refs) ;
66 }
67
68 ##############################################################################
69
70 local rule resolve-reference ( target-ref : caller-mod caller-dir ? )
71 {
72 # ECHO %%% modular.resolve-target-ref $(target-ref) :: $(caller-mod) $(caller-dir) ;
73 if ! $(caller-dir)
74 {
75 caller-dir = [ modules.peek $(caller-mod) : __file__ ] ;
76 caller-dir = $(caller-dir:D) ;
77 caller-dir = [ path.root $(caller-dir) [ path.pwd ] ] ;
78 }
79 local result-ref = $(target-ref) ;
80 local ref = [ MATCH ^(.*)//.* : $(target-ref:G=) ] ;
81 # if ! ( $(ref) in $(.target-refs) )
82 {
83 # .target-refs += $(ref) ;
84 local search-prefix ;
85 local search-sub ;
86 for local prefix in $(.search-path-prefix)
87 {
88 if ! $(search-prefix)
89 {
90 local search-match = [ MATCH ^($(prefix))/(.*)$ : $(ref) ] ;
91 search-prefix = $(search-match[1]) ;
92 search-sub = $(search-match[2]) ;
93 }
94 }
95
96 if $(search-prefix)
97 {
98 local found = [ path.glob $(.search-path.$(search-prefix)) : $(search-sub) ] ;
99 found = $(found[1]) ;
100 if $(found)
101 {
102 local lib-ref = [ regex.split $(search-sub) / ] ;
103 lib-ref = $(search-prefix)/$(lib-ref[1]) ;
104 local lib-path = [ path.relative-to $(caller-dir) $(found) ] ;
105 define-library $(lib-ref) $(caller-mod) : $(lib-path) ;
106 }
107 }
108 }
109 return $(result-ref) ;
110 }
111
112 local rule define-library ( name caller-module ? : root )
113 {
114 # ECHO ~~~ modular.library $(name) $(caller-module) :: $(root) :: $(depends) ;
115
116 process-args ;
117
118 # Dir path of caller to base paths from.
119 caller-module ?= [ CALLER_MODULE ] ;
120 local caller-dir = [ modules.peek $(caller-module) : __file__ ] ;
121 caller-dir = $(caller-dir:D) ;
122
123 # Find the various parts of the library.
124 local lib-dir = [ path.root [ path.root $(root) $(caller-dir) ] [ path.pwd ] ] ;
125 local lib-contents = [ path.glob $(lib-dir) : "include" "build" ] ;
126 lib-contents = $(lib-contents:D=) ;
127
128 # "include" dir for library..
129 local include-dir ;
130 if "include" in $(lib-contents)
131 {
132 include-dir = $(root)/include ;
133 }
134
135 # If it has a build dir, i.e. it has targets to build,
136 # we root the project at the build dir to make it easy
137 # to refer to the build targets. This mirrors the regular
138 # Boost organization of the project aliases.
139 if "build" in $(lib-contents)
140 {
141 root = $(root)/build ;
142 build-dir = "." ;
143 }
144
145 # Shadow target declarations so that we can alter build targets
146 # to work in the standalone modular structure.
147 local lib-location = [ path.root [ path.make $(root) ] $(caller-dir) ] ;
148 local lib-module-name = [ project.module-name $(lib-location) ] ;
149 local modular-rules = [ RULENAMES modular-rules ] ;
150 IMPORT modular-rules : $(modular-rules) : $(lib-module-name) : $(modular-rules) ;
151
152 # Load/create/declare library project.
153 local lib-module = [ project.find $(root) : $(caller-dir) ] ;
154 if ! $(lib-module)
155 {
156 # If the find was unable to load the project we synthesize it.
157 lib-module = [ project.load $(lib-location) : synthesize ] ;
158 }
159 local lib-target = [ project.target $(lib-module) ] ;
160 if ! [ modules.peek $(lib-module) : __library__ ]
161 {
162 modules.poke $(lib-module) : __library__ : $(name) ;
163 for local type in [ modules.peek type : .types ]
164 {
165 main-rule-name = [ type.type-to-rule-name $(type) ] ;
166 IMPORT modular-rules : main-target-rule : $(lib-module-name) : $(main-rule-name) ;
167 }
168 }
169
170 # Declare project alternate ID.
171 modules.call-in $(caller-module) : use-project $(name) : $(root) ;
172
173 # Create a "library" target that has basic usage info if needed.
174 if ! [ $(lib-target).has-alternative-for-target library ]
175 {
176 include-dir = [ path.relative-to $(root) $(include-dir) ] ;
177
178 project.push-current $(lib-target) ;
179
180 # Declare the library alias.
181 modules.call-in $(lib-module) : library
182 : # Sources
183 : # Requirements
184 : # Default Build
185 : # Usage Requirements
186 <include>$(include-dir)
187 ;
188
189 project.pop-current ;
190 }
191 }
192
193 local rule process-args ( )
194 {
195 if ! $(.did-process-args)
196 {
197 .did-process-args = yes ;
198 local argv = [ modules.peek : ARGV ] ;
199 local dirs = [ MATCH ^--modular-search-dir=(.*)$ : $(argv) ] ;
200 for local dir in $(dirs)
201 {
202 add-location $(dir) : [ path.pwd ] ;
203 }
204 }
205 }
206
207 rule apply-external (
208 mod : field : values * )
209 {
210 local result ;
211 local name = [ modules.peek $(mod) : __library__ ] ;
212 values += $(.external.($(name)).$(field)) ;
213 for local value in $(values)
214 {
215 result += [ resolve-reference $(value) : $(mod) ] ;
216 }
217 return $(result) ;
218 }
219
220 module modular-rules
221 {
222 import type ;
223 import targets ;
224 import builtin ;
225 import alias ;
226
227 # Avoids any form of installation for Boost modules.
228 rule boost-install ( libraries * ) { }
229
230 # Generic typed target rule to pre-process main target
231 # declarations to make them work within the standalone
232 # modular structure.
233 rule main-target-rule (
234 name : sources * : requirements * : default-build * :
235 usage-requirements * )
236 {
237 local mod = [ CALLER_MODULE ] ;
238
239 # ECHO @@@ [[$(mod)]] modular-rules.main-target-rule $(name) :: $(sources) :: $(requirements) :: $(default-build) :: $(usage-requirements) ;
240
241 # First discover the required target type based on the exact alias used to
242 # invoke this rule.
243 local bt = [ BACKTRACE 1 ] ;
244 local rulename = $(bt[4]) ;
245 local target-type = [ type.type-from-rule-name $(rulename) ] ;
246 return [ targets.create-typed-target $(target-type) : [ project.current ] :
247 $(name) : $(sources) : $(requirements) : $(default-build) :
248 $(usage-requirements) ] ;
249 }
250
251 rule lib ( names + : sources * : requirements * : default-build * :
252 usage-requirements * )
253 {
254 local mod = [ CALLER_MODULE ] ;
255 requirements += <use>library ;
256 usage-requirements += <use>library ;
257
258 # ECHO @@@ [[$(mod)]] modular-rules.lib $(names) :: $(sources) :: $(requirements) :: $(default-build) :: $(usage-requirements) ;
259 return [ builtin.lib $(names) : $(sources) : $(requirements) : $(default-build) : $(usage-requirements) ] ;
260 }
261
262 rule alias ( name : sources * : requirements * : default-build * :
263 usage-requirements * )
264 {
265 local mod = [ CALLER_MODULE ] ;
266
267 # ECHO @@@ [[$(mod)]] modular-rules.alias $(name) :: $(sources) :: $(requirements) :: $(default-build) :: $(usage-requirements) ;
268 return [ alias.alias $(name) : $(sources) : $(requirements) : $(default-build) : $(usage-requirements) ] ;
269 }
270
271 rule library ( name ? : sources * : requirements * : default-build * :
272 usage-requirements * )
273 {
274 import modular ;
275
276 local mod = [ CALLER_MODULE ] ;
277 sources = [ modular.apply-external $(mod) : sources : $(sources) ] ;
278 requirements = [ modular.apply-external $(mod) : requirements : $(requirements) ] ;
279 default-build = [ modular.apply-external $(mod) : default-build : $(default-build) ] ;
280 usage-requirements = [ modular.apply-external $(mod) : usage-requirements : $(usage-requirements) ] ;
281
282 name ?= library ;
283
284 # ECHO @@@ [[$(mod)]] modular-rules.library $(name) :: $(sources) :: $(requirements) :: $(default-build) :: $(usage-requirements) ;
285 return [ alias.alias $(name) : $(sources) : $(requirements) : $(default-build) : $(usage-requirements) ] ;
286 }
287 }
288