1 | <html> |
---|
2 | <head> |
---|
3 | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
---|
4 | <title>Targets</title> |
---|
5 | <link rel="stylesheet" href="../../boostbook.css" type="text/css"> |
---|
6 | <meta name="generator" content="DocBook XSL Stylesheets V1.69.1"> |
---|
7 | <style type="text/css"> |
---|
8 | body { background-image: url('http://docbook.sourceforge.net/release/images/draft.png'); |
---|
9 | background-repeat: no-repeat; |
---|
10 | background-position: top left; |
---|
11 | /* The following properties make the watermark "fixed" on the page. */ |
---|
12 | /* I think that's just a bit too distracting for the reader... */ |
---|
13 | /* background-attachment: fixed; */ |
---|
14 | /* background-position: center center; */ |
---|
15 | }</style> |
---|
16 | <link rel="start" href="../../index.html" title="The Boost C++ Libraries"> |
---|
17 | <link rel="up" href="../arch.html" title="Appendix B. Boost.Build v2 architecture"> |
---|
18 | <link rel="prev" href="tools.html" title="The tools layer"> |
---|
19 | <link rel="next" href="../../who_s_using_boost_.html" title="Who's Using Boost?"> |
---|
20 | </head> |
---|
21 | <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> |
---|
22 | <table cellpadding="2" width="100%"> |
---|
23 | <td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td> |
---|
24 | <td align="center"><a href="../../../../index.htm">Home</a></td> |
---|
25 | <td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td> |
---|
26 | <td align="center"><a href="../../../../people/people.htm">People</a></td> |
---|
27 | <td align="center"><a href="../../../../more/faq.htm">FAQ</a></td> |
---|
28 | <td align="center"><a href="../../../../more/index.htm">More</a></td> |
---|
29 | </table> |
---|
30 | <hr> |
---|
31 | <div class="spirit-nav"> |
---|
32 | <a accesskey="p" href="tools.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../arch.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../../who_s_using_boost_.html"><img src="../../images/next.png" alt="Next"></a> |
---|
33 | </div> |
---|
34 | <div class="section" lang="en"> |
---|
35 | <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
---|
36 | <a name="bbv2.arch.targets"></a>Targets</h2></div></div></div> |
---|
37 | <div class="toc"><dl><dt><span class="section"><a href="targets.html#bbv2.arch.depends">Dependency scanning</a></span></dt></dl></div> |
---|
38 | <p>NOTE: THIS SECTION IS NOT EXPECTED TO BE READ! |
---|
39 | There are two user-visible kinds of targets in Boost.Build. |
---|
40 | First are "abstract" — they correspond to things declared |
---|
41 | by user, for example, projects and executable files. The primary |
---|
42 | thing about abstract target is that it's possible to request them |
---|
43 | to be build with a particular values of some properties. Each |
---|
44 | combination of properties may possible yield different set of |
---|
45 | real file, so abstract target do not have a direct correspondence |
---|
46 | with files.</p> |
---|
47 | <p>File targets, on the contary, are associated with concrete |
---|
48 | files. Dependency graphs for abstract targets with specific |
---|
49 | properties are constructed from file targets. User has no was to |
---|
50 | create file targets, however it can specify rules that detect |
---|
51 | file type for sources, and also rules for transforming between |
---|
52 | file targets of different types. That information is used in |
---|
53 | constructing dependency graph, as desribed in the "next section". |
---|
54 | [ link? ] <span class="bold"><strong>Note:</strong></span>File targets are not |
---|
55 | the same as targets in Jam sense; the latter are created from |
---|
56 | file targets at the latest possible moment. <span class="bold"><strong>Note:</strong></span>"File |
---|
57 | target" is a proposed name for what we call virtual targets. It |
---|
58 | it more understandable by users, but has one problem: virtual |
---|
59 | targets can potentially be "phony", and not correspond to any |
---|
60 | file.</p> |
---|
61 | <div class="section" lang="en"> |
---|
62 | <div class="titlepage"><div><div><h3 class="title"> |
---|
63 | <a name="bbv2.arch.depends"></a>Dependency scanning</h3></div></div></div> |
---|
64 | <div class="toc"><dl> |
---|
65 | <dt><span class="section"><a href="targets.html#id2862570">Support for different scanning algorithms</a></span></dt> |
---|
66 | <dt><span class="section"><a href="targets.html#id2862579">Ability to scan the same file several times</a></span></dt> |
---|
67 | <dt><span class="section"><a href="targets.html#id2862640">Proper detection of dependencies on generated files.</a></span></dt> |
---|
68 | <dt><span class="section"><a href="targets.html#id2862819">Proper detection of dependencies from generated files</a></span></dt> |
---|
69 | </dl></div> |
---|
70 | <p>Dependency scanning is the process of finding implicit |
---|
71 | dependencies, like "#include" statements in C++. The requirements |
---|
72 | for right dependency scanning mechanism are:</p> |
---|
73 | <div class="itemizedlist"><ul type="disc"> |
---|
74 | <li> |
---|
75 | Support for different scanning algorithms. C++ and XML have |
---|
76 | quite different syntax for includes and rules for looking up |
---|
77 | included files. |
---|
78 | </li> |
---|
79 | <li> |
---|
80 | Ability to scan the same file several times. For example, |
---|
81 | single C++ file can be compiled with different include |
---|
82 | paths. |
---|
83 | </li> |
---|
84 | <li> |
---|
85 | Proper detection of dependencies on generated files. |
---|
86 | </li> |
---|
87 | <li> |
---|
88 | Proper detection of dependencies from generated file. |
---|
89 | </li> |
---|
90 | </ul></div> |
---|
91 | <div class="section" lang="en"> |
---|
92 | <div class="titlepage"><div><div><h4 class="title"> |
---|
93 | <a name="id2862570"></a>Support for different scanning algorithms</h4></div></div></div> |
---|
94 | <p>Different scanning algorithm are encapsulated by objects |
---|
95 | called "scanners". Please see the documentation for "scanner" |
---|
96 | module for more details.</p> |
---|
97 | </div> |
---|
98 | <div class="section" lang="en"> |
---|
99 | <div class="titlepage"><div><div><h4 class="title"> |
---|
100 | <a name="id2862579"></a>Ability to scan the same file several times</h4></div></div></div> |
---|
101 | <p>As said above, it's possible to compile a C++ file twice, with |
---|
102 | different include paths. Therefore, include dependencies for |
---|
103 | those compilations can be different. The problem is that bjam |
---|
104 | does not allow several scans of the same target.</p> |
---|
105 | <p>The solution in Boost.Build is straigtforward. When a virtual |
---|
106 | target is converted to bjam target (via |
---|
107 | <code class="literal">virtual-target.actualize</code> method), we specify the scanner |
---|
108 | object to be used. The actualize method will create different |
---|
109 | bjam targets for different scanners.</p> |
---|
110 | <p>All targets with specific scanner are made dependent on target |
---|
111 | without scanner, which target is always created. This is done in |
---|
112 | case the target is updated. The updating action will be |
---|
113 | associated with target without scanner, but if sources for that |
---|
114 | action are touched, all targets — with scanner and without |
---|
115 | should be considered outdated.</p> |
---|
116 | <p>For example, assume that "a.cpp" is compiled by two compilers |
---|
117 | with different include path. It's also copied into some install |
---|
118 | location. In turn, it's produced from "a.verbatim". The |
---|
119 | dependency graph will look like:</p> |
---|
120 | <pre class="programlisting"> |
---|
121 | a.o (<toolset>gcc) <--(compile)-- a.cpp (scanner1) ----+ |
---|
122 | a.o (<toolset>msvc) <--(compile)-- a.cpp (scanner2) ----| |
---|
123 | a.cpp (installed copy) <--(copy) ----------------------- a.cpp (no scanner) |
---|
124 | ^ |
---|
125 | | |
---|
126 | a.verbose --------------------------------+ |
---|
127 | </pre> |
---|
128 | </div> |
---|
129 | <div class="section" lang="en"> |
---|
130 | <div class="titlepage"><div><div><h4 class="title"> |
---|
131 | <a name="id2862640"></a>Proper detection of dependencies on generated files.</h4></div></div></div> |
---|
132 | <p>This requirement breaks down to the following ones.</p> |
---|
133 | <div class="orderedlist"><ol type="1"> |
---|
134 | <li> |
---|
135 | If when compiling "a.cpp" there's include of "a.h", the |
---|
136 | "dir" directory is in include path, and a target called "a.h" |
---|
137 | will be generated to "dir", then bjam should discover the |
---|
138 | include, and create "a.h" before compiling "a.cpp". |
---|
139 | </li> |
---|
140 | <li> |
---|
141 | Since almost always Boost.Build generates targets to a |
---|
142 | "bin" directory, it should be supported as well. I.e. in the |
---|
143 | scanario above, Jamfile in "dir" might create a main target, |
---|
144 | which generates "a.h". The file will be generated to "dir/bin" |
---|
145 | directory, but we still have to recornize the dependency. |
---|
146 | </li> |
---|
147 | </ol></div> |
---|
148 | <p>The first requirement means that when determining what "a.h" |
---|
149 | means, when found in "a.cpp", we have to iterate over all |
---|
150 | directories in include paths, checking for each one:</p> |
---|
151 | <div class="orderedlist"><ol type="1"> |
---|
152 | <li> |
---|
153 | If there's file "a.h" in that directory, or |
---|
154 | </li> |
---|
155 | <li> |
---|
156 | If there's a target called "a.h", which will be generated |
---|
157 | to that directory. |
---|
158 | </li> |
---|
159 | </ol></div> |
---|
160 | <p>Classic Jam has built-in facilities for point (1) above, but |
---|
161 | that's not enough. It's hard to implement the right semantic |
---|
162 | without builtin support. For example, we could try to check if |
---|
163 | there's targer called "a.h" somewhere in dependency graph, and |
---|
164 | add a dependency to it. The problem is that without search in |
---|
165 | include path, the semantic may be incorrect. For example, one can |
---|
166 | have an action which generated some "dummy" header, for system |
---|
167 | which don't have the native one. Naturally, we don't want to |
---|
168 | depend on that generated header on platforms where native one is |
---|
169 | included.</p> |
---|
170 | <p>There are two design choices for builtin support. Suppose we |
---|
171 | have files a.cpp and b.cpp, and each one includes header.h, |
---|
172 | generated by some action. Dependency graph created by classic jam |
---|
173 | would look like:</p> |
---|
174 | <pre class="programlisting"> |
---|
175 | a.cpp -----> <scanner1>header.h [search path: d1, d2, d3] |
---|
176 | |
---|
177 | |
---|
178 | <d2>header.h --------> header.y |
---|
179 | [generated in d2] |
---|
180 | |
---|
181 | b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4] |
---|
182 | </pre> |
---|
183 | <p> |
---|
184 | In this case, Jam thinks all header.h target are not |
---|
185 | realated. The right dependency graph might be: |
---|
186 | |
---|
187 | </p> |
---|
188 | <pre class="programlisting"> |
---|
189 | a.cpp ---- |
---|
190 | \ |
---|
191 | \ |
---|
192 | >----> <d2>header.h --------> header.y |
---|
193 | / [generated in d2] |
---|
194 | / |
---|
195 | b.cpp ---- |
---|
196 | </pre> |
---|
197 | <p> |
---|
198 | |
---|
199 | or |
---|
200 | |
---|
201 | </p> |
---|
202 | <pre class="programlisting"> |
---|
203 | a.cpp -----> <scanner1>header.h [search path: d1, d2, d3] |
---|
204 | | |
---|
205 | (includes) |
---|
206 | V |
---|
207 | <d2>header.h --------> header.y |
---|
208 | [generated in d2] |
---|
209 | ^ |
---|
210 | (includes) |
---|
211 | | |
---|
212 | b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4] |
---|
213 | </pre> |
---|
214 | <p> |
---|
215 | The first alternative was used for some time. The problem |
---|
216 | however is: what include paths should be used when scanning |
---|
217 | header.h? The second alternative was suggested by Matt Armstrong. |
---|
218 | It has similiar effect: add targets which depend on |
---|
219 | <scanner1>header.h will also depend on <d2>header.h. |
---|
220 | But now we have two different target with two different scanners, |
---|
221 | and those targets can be scanned independently. The problem of |
---|
222 | first alternative is avoided, so the second alternative is |
---|
223 | implemented now. |
---|
224 | </p> |
---|
225 | <p>The second sub-requirements is that targets generated to "bin" |
---|
226 | directory are handled as well. Boost.Build implements |
---|
227 | semi-automatic approach. When compiling C++ files the process |
---|
228 | is:</p> |
---|
229 | <div class="orderedlist"><ol type="1"> |
---|
230 | <li> |
---|
231 | The main target to which compiled file belongs is found. |
---|
232 | </li> |
---|
233 | <li> |
---|
234 | All other main targets that the found one depends on are |
---|
235 | found. Those include main target which are used as sources, or |
---|
236 | present as values of "dependency" features. |
---|
237 | </li> |
---|
238 | <li> |
---|
239 | All directories where files belonging to those main target |
---|
240 | will be generated are added to the include path. |
---|
241 | </li> |
---|
242 | </ol></div> |
---|
243 | <p>After this is done, dependencies are found by the approach |
---|
244 | explained previously.</p> |
---|
245 | <p>Note that if a target uses generated headers from other main |
---|
246 | target, that main target should be explicitly specified as |
---|
247 | dependency property. It would be better to lift this requirement, |
---|
248 | but it seems not very problematic in practice.</p> |
---|
249 | <p>For target types other than C++, adding of include paths must |
---|
250 | be implemented anew.</p> |
---|
251 | </div> |
---|
252 | <div class="section" lang="en"> |
---|
253 | <div class="titlepage"><div><div><h4 class="title"> |
---|
254 | <a name="id2862819"></a>Proper detection of dependencies from generated files</h4></div></div></div> |
---|
255 | <div class="toc"><dl> |
---|
256 | <dt><span class="section"><a href="targets.html#id2862929">File targets</a></span></dt> |
---|
257 | <dt><span class="section"><a href="targets.html#id2862965">Target paths</a></span></dt> |
---|
258 | </dl></div> |
---|
259 | <p>Suppose file "a.cpp" includes "a.h" and both are generated by |
---|
260 | some action. Note that classic jam has two stages. In first stage |
---|
261 | dependency graph graph is build and actions which should be run |
---|
262 | are determined. In second stage the actions are executed. |
---|
263 | Initially, neither file exists, so the include is not found. As |
---|
264 | the result, jam might attempt to compile a.cpp before creating |
---|
265 | a.h, and compilation will fail.</p> |
---|
266 | <p>The solution in Boost.Jam is to perform additional dependency |
---|
267 | scans after targets are updated. This break separation between |
---|
268 | build stages in jam — which some people consider a good |
---|
269 | thing — but I'm not aware of any better solution.</p> |
---|
270 | <p>In order to understand the rest of this section, you better |
---|
271 | read some details about jam dependency scanning, available |
---|
272 | <a href="http://public.perforce.com:8080/@md=d&cd=//public/jam/src/&ra=s&c=kVu@//2614?ac=10" target="_top"> |
---|
273 | at this link</a>.</p> |
---|
274 | <p>Whenever a target is updated, Boost.Jam rescans it for |
---|
275 | includes. Consider this graph, created before any actions are |
---|
276 | run.</p> |
---|
277 | <pre class="programlisting"> |
---|
278 | A -------> C ----> C.pro |
---|
279 | / |
---|
280 | B --/ C-includes ---> D |
---|
281 | </pre> |
---|
282 | <p> |
---|
283 | Both A and B have dependency on C and C-includes (the latter |
---|
284 | dependency is not shown). Say during building we've tried to create |
---|
285 | A, then tried to create C and successfully created C. |
---|
286 | </p> |
---|
287 | <p>In that case, the set of includes in C might well have |
---|
288 | changed. We do not bother to detect precisely which includes were |
---|
289 | added or removed. Instead we create another internal node |
---|
290 | C-includes-2. Then we determine what actions should be run to |
---|
291 | update the target. In fact this mean that we perform logic of |
---|
292 | first stage while already executing stage.</p> |
---|
293 | <p>After actions for C-includes-2 are determined, we add |
---|
294 | C-includes-2 to the list of A's dependents, and stage 2 proceeds |
---|
295 | as usual. Unfortunately, we can't do the same with target B, |
---|
296 | since when it's not visited, C target does not know B depends on |
---|
297 | it. So, we add a flag to C which tells and it was rescanned. When |
---|
298 | visiting B target, the flag is notices and C-includes-2 will be |
---|
299 | added to the list of B's dependencies.</p> |
---|
300 | <p>Note also that internal nodes are sometimes updated too. |
---|
301 | Consider this dependency graph:</p> |
---|
302 | <pre class="programlisting"> |
---|
303 | a.o ---> a.cpp |
---|
304 | a.cpp-includes --> a.h (scanned) |
---|
305 | a.h-includes ------> a.h (generated) |
---|
306 | | |
---|
307 | | |
---|
308 | a.pro <-------------------------------------------+ |
---|
309 | </pre> |
---|
310 | <p>Here, out handling of generated headers come into play. Say |
---|
311 | that a.h exists but is out of date with respect to "a.pro", then |
---|
312 | "a.h (generated)" and "a.h-includes" will be marking for |
---|
313 | updating, but "a.h (scanned)" won't be marked. We have to rescan |
---|
314 | "a.h" file after it's created, but since "a.h (generated)" has no |
---|
315 | scanner associated with it, it's only possible to rescan "a.h" |
---|
316 | after "a.h-includes" target was updated.</p> |
---|
317 | <p>Tbe above consideration lead to decision that we'll rescan a |
---|
318 | target whenever it's updated, no matter if this target is |
---|
319 | internal or not.</p> |
---|
320 | <div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"> |
---|
321 | <h3 class="title">Warning</h3> |
---|
322 | <p> |
---|
323 | The remainder of this document is not indended to be read at |
---|
324 | all. This will be rearranged in future. |
---|
325 | </p> |
---|
326 | </div> |
---|
327 | <div class="section" lang="en"> |
---|
328 | <div class="titlepage"><div><div><h5 class="title"> |
---|
329 | <a name="id2862929"></a>File targets</h5></div></div></div> |
---|
330 | <p> |
---|
331 | As described above, file targets corresponds |
---|
332 | to files that Boost.Build manages. User's may be concerned about |
---|
333 | file targets in three ways: when declaring file target types, |
---|
334 | when declaring transformations between types, and when |
---|
335 | determining where file target will be placed. File targets can |
---|
336 | also be connected with actions, that determine how the target is |
---|
337 | created. Both file targets and actions are implemented in the |
---|
338 | <code class="literal">virtual-target</code> module. |
---|
339 | </p> |
---|
340 | <div class="section" lang="en"> |
---|
341 | <div class="titlepage"><div><div><h6 class="title"> |
---|
342 | <a name="id2862948"></a>Types</h6></div></div></div> |
---|
343 | <p>A file target can be given a file, which determines |
---|
344 | what transformations can be applied to the file. The |
---|
345 | <code class="literal">type.register</code> rule declares new types. File type can |
---|
346 | also be assigned a scanner, which is used to find implicit |
---|
347 | dependencies. See "dependency scanning" [ link? ] below.</p> |
---|
348 | </div> |
---|
349 | </div> |
---|
350 | <div class="section" lang="en"> |
---|
351 | <div class="titlepage"><div><div><h5 class="title"> |
---|
352 | <a name="id2862965"></a>Target paths</h5></div></div></div> |
---|
353 | <p>To distinguish targets build with different properties, they |
---|
354 | are put in different directories. Rules for determining target |
---|
355 | paths are given below:</p> |
---|
356 | <div class="orderedlist"><ol type="1"> |
---|
357 | <li> |
---|
358 | All targets are placed under directory corresponding to the |
---|
359 | project where they are defined. |
---|
360 | </li> |
---|
361 | <li> |
---|
362 | Each non free, non incidental property cause an additional |
---|
363 | element to be added to the target path. That element has the |
---|
364 | form <code class="literal"><feature-name>-<feature-value></code> for |
---|
365 | ordinary features and <code class="literal"><feature-value></code> for |
---|
366 | implicit ones. [Note about composite features]. |
---|
367 | </li> |
---|
368 | <li> |
---|
369 | If the set of free, non incidental properties is different |
---|
370 | from the set of free, non incidental properties for the project |
---|
371 | in which the main target that uses the target is defined, a |
---|
372 | part of the form <code class="literal">main_target-<name></code> is added to |
---|
373 | the target path. <span class="bold"><strong>Note:</strong></span>It would be nice to completely |
---|
374 | track free features also, but this appears to be complex and |
---|
375 | not extremely needed. |
---|
376 | </li> |
---|
377 | </ol></div> |
---|
378 | <p>For example, we might have these paths:</p> |
---|
379 | <pre class="programlisting"> |
---|
380 | debug/optimization-off |
---|
381 | debug/main-target-a |
---|
382 | </pre> |
---|
383 | </div> |
---|
384 | </div> |
---|
385 | </div> |
---|
386 | </div> |
---|
387 | <table width="100%"><tr> |
---|
388 | <td align="left"></td> |
---|
389 | <td align="right"><small></small></td> |
---|
390 | </tr></table> |
---|
391 | <hr> |
---|
392 | <div class="spirit-nav"> |
---|
393 | <a accesskey="p" href="tools.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../arch.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../../who_s_using_boost_.html"><img src="../../images/next.png" alt="Next"></a> |
---|
394 | </div> |
---|
395 | </body> |
---|
396 | </html> |
---|