Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/doc/html/bbv2/arch/targets.html @ 12

Last change on this file since 12 was 12, checked in by landauf, 18 years ago

added boost

File size: 18.6 KB
Line 
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">
8body { 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" &#8212; 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 &#8212; 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">
121a.o (&lt;toolset&gt;gcc)  &lt;--(compile)-- a.cpp (scanner1) ----+
122a.o (&lt;toolset&gt;msvc) &lt;--(compile)-- a.cpp (scanner2) ----|
123a.cpp (installed copy)    &lt;--(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">
175a.cpp -----&gt; &lt;scanner1&gt;header.h  [search path: d1, d2, d3]
176
177
178                  &lt;d2&gt;header.h  --------&gt; header.y
179                  [generated in d2]
180           
181b.cpp -----&gt; &lt;scanner2&gt;header.h [ search path: d1, d2, d4]
182</pre>
183<p>
184In this case, Jam thinks all header.h target are not
185realated. The right dependency graph might be:
186
187</p>
188<pre class="programlisting">
189a.cpp ----
190          \
191           \     
192            &gt;----&gt;  &lt;d2&gt;header.h  --------&gt; header.y
193           /       [generated in d2]
194          /
195b.cpp ----
196</pre>
197<p>
198
199or
200
201</p>
202<pre class="programlisting">
203a.cpp -----&gt; &lt;scanner1&gt;header.h  [search path: d1, d2, d3]
204                          |
205                       (includes)
206                          V
207                  &lt;d2&gt;header.h  --------&gt; header.y
208                  [generated in d2]
209                          ^
210                      (includes) 
211                          |
212b.cpp -----&gt; &lt;scanner2&gt;header.h [ search path: d1, d2, d4]
213</pre>
214<p>
215The first alternative was used for some time. The problem
216however is: what include paths should be used when scanning
217header.h? The second alternative was suggested by Matt Armstrong.
218It has similiar effect: add targets which depend on
219&lt;scanner1&gt;header.h will also depend on &lt;d2&gt;header.h.
220But now we have two different target with two different scanners,
221and those targets can be scanned independently. The problem of
222first alternative is avoided, so the second alternative is
223implemented 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 &#8212; which some people consider a good
269  thing &#8212; 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&amp;cd=//public/jam/src/&amp;ra=s&amp;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">
278A -------&gt; C ----&gt; C.pro
279     /
280B --/         C-includes   ---&gt; D
281</pre>
282<p>
283Both A and B have dependency on C and C-includes (the latter
284dependency is not shown). Say during building we've tried to create
285A, 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">
303a.o ---&gt; a.cpp
304            a.cpp-includes --&gt;  a.h (scanned)
305                                   a.h-includes ------&gt; a.h (generated)
306                                                                 |
307                                                                 |
308            a.pro &lt;-------------------------------------------+
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">&lt;feature-name&gt;-&lt;feature-value&gt;</code> for
365    ordinary features and <code class="literal">&lt;feature-value&gt;</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-&lt;name&gt;</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">
380debug/optimization-off
381debug/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>
Note: See TracBrowser for help on using the repository browser.