Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/tools/build/v2/doc/src/faq.xml @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 15.0 KB
Line 
1<?xml version="1.0" standalone="yes"?>
2<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
3     "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
4
5  <chapter id="bbv2.faq">
6    <title>Frequently Asked Questions</title>
7
8    <section>
9      <title>
10        How do I get the current value of feature in Jamfile?
11      </title>
12
13      <para>
14        This is not possible, since Jamfile does not have "current" value of any
15        feature, be it toolset, build variant or anything else. For a single invocation of
16        <filename>bjam</filename>, any given main target can be built with several property sets.
17        For example, user can request two build variants on the command line. Or one library
18        is built as shared when used from one application, and as static when used from another.
19        Obviously, Jamfile is read only once, so generally, there's no single value of a feature
20        you can access in Jamfile.               
21      </para>
22
23      <para>A feature has a specific value only when building a target, and there are two ways how you
24      can use that value:</para>
25      <itemizedlist>
26        <listitem><simpara>Use conditional requirements or indirect conditional requirements. See
27        <xref linkend="bbv2.advanced.targets.requirements.conditional"/>.</simpara>
28        </listitem>
29        <listitem>Define a custom generator and a custom main target type. The custom generator can do arbitrary processing
30        or properties. See the <xref linkend="bbv2.extender">extender manual</xref>.
31        </listitem>               
32      </itemizedlist>
33
34    </section>
35
36    <section>
37      <title>
38        I'm getting "Duplicate name of actual target" error. What
39        does it mean?
40      </title>
41
42    <para>   
43    The most likely case is that you're trying to
44    compile the same file twice, with almost the same,
45    but differing properties. For example:
46
47<programlisting>
48exe a : a.cpp : &lt;include&gt;/usr/local/include ;
49exe b : a.cpp ;
50</programlisting>   
51
52    </para>
53
54    <para>
55    The above snippet requires two different compilations
56    of 'a.cpp', which differ only in 'include' property.
57    Since the 'include' property is free, Boost.Build
58    can't generate two objects files into different directories.
59    On the other hand, it's dangerous to compile the file only
60    once -- maybe you really want to compile with different
61    includes.
62    </para>
63
64    <para>
65    To solve this issue, you need to decide if file should
66    be compiled once or twice.</para>
67
68    <orderedlist>
69    <listitem>
70    <para>Two compile file only once, make sure that properties
71      are the same:
72
73<programlisting>
74exe a : a.cpp : &lt;include&gt;/usr/local/include ;
75exe b : a.cpp : &lt;include&gt;/usr/local/include ;
76</programlisting></para></listitem>
77
78    <listitem><para>
79      If changing the properties is not desirable, for example
80      if 'a' and 'b' target have other sources which need
81      specific properties, separate 'a.cpp' into it's own target:
82
83<programlisting>
84obj a_obj : a.cpp : &lt;include&gt;/usr/local/include ;
85exe a : a_obj ;
86</programlisting></para></listitem>
87   
88      <listitem><para>
89      To compile file twice, you can make the object file local
90      to the main target:
91
92<programlisting>
93      exe a : [ obj a_obj : a.cpp ] : &lt;include&gt;/usr/local/include ;
94      exe b : [ obj a_obj : a.cpp ] ;
95</programlisting></para></listitem>
96
97   </orderedlist>
98
99   <para>
100   A good question is why Boost.Build can't use some of the above
101   approaches automatically. The problem is that such magic would
102   require additional implementation complexities and would only
103   help in half of the cases, while in other half we'd be silently
104   doing the wrong thing. It's simpler and safe to ask user to
105   clarify his intention in such cases.
106   </para>
107
108    </section>
109
110    <section id="bbv2.faq.envar">
111      <title>
112      Accessing environment variables
113      </title>
114
115    <para>   
116      Many users would like to use environment variables in Jamfiles, for
117      example, to control location of external libraries. In many cases you
118      better declare those external libraries in the site-config.jam file, as
119      documented in the <link linkend="bbv2.recipies.site-config">recipes
120      section</link>. However, if the users already have the environment variables set
121      up, it's not convenient to ask them to set up site-config.jam files as
122      well, and using environment variables might be reasonable.
123    </para>
124
125    <para>In Boost.Build V2, each Jamfile is a separate namespace, and the
126    variables defined in environment is imported into the global
127    namespace. Therefore, to access environment variable from Jamfile, you'd
128    need the following code:
129<programlisting>
130import os ;
131local SOME_LIBRARY_PATH = [ os.environ SOME_LIBRARY_PATH ] ;
132exe a : a.cpp : &lt;include&gt;$(SOME_LIBRARY_PATH) ;
133</programlisting>
134    </para>
135</section>
136
137    <section>
138      <title>
139        How to control properties order?
140      </title>
141
142    <para>For internal reasons, Boost.Build sorts all the properties
143    alphabetically. This means that if you write:
144<programlisting>
145exe a : a.cpp : &lt;include&gt;b &lt;include&gt;a ;
146</programlisting>
147      then the command line with first mention the "a" include directory, and
148      then "b", even though they are specified in the opposite order. In most
149      cases, the user doesn't care. But sometimes the order of includes, or
150      other properties, is important. For example, if one uses both the C++
151      Boost library and the "boost-sandbox" (libraries in development), then
152      include path for boost-sandbox must come first, because some headers may
153      override ones in C++ Boost. For such cases, a special syntax is
154      provided:
155<programlisting>
156exe a : a.cpp : &lt;include&gt;a&amp;&amp;b ;       
157</programlisting>
158    </para>
159
160    <para>The <code>&amp;&amp;</code> symbols separate values of an
161      property, and specify that the order of the values should be preserved. You
162      are advised to use this feature only when the order of properties really
163      matters, and not as a convenient shortcut. Using it everywhere might
164      negatively affect performance.
165    </para>
166
167  </section>
168
169  <section>
170    <title>
171      How to control the library order on Unix?
172    </title>
173
174    <para>On the Unix-like operating systems, the order in which static
175      libraries are specified when invoking the linker is important, because by
176      default, the linker uses one pass though the libraries list. Passing the
177      libraries in the incorrect order will lead to a link error. Further, this
178      behaviour is often used to make one library override symbols from
179      another. So, sometimes it's necessary to force specific order of
180      libraries.   
181    </para>
182
183    <para>Boost.Build tries to automatically compute the right order.  The
184      primary rule is that if library a "uses" library b, then library a will
185      appear on the command line before library b. Library a is considered to
186      use b is b is present either in the sources of a or in its
187      requirements. To explicitly specify the use relationship one can use the
188      &lt;use&gt; feature. For example, both of the following lines will cause
189      a to appear before b on the command line:
190<programlisting>
191lib a : a.cpp b ;
192lib a : a.cpp : &lt;use&gt;b ;
193</programlisting>
194    </para>
195
196    <para>
197      The same approach works for searched libraries, too:
198<programlisting>
199lib z ;
200lib png : : &lt;use&gt;z ;
201exe viewer : viewer png z ;
202</programlisting>
203    </para>
204
205  </section>
206
207  <section id="bbv2.faq.external">
208    <title>Can I get output of external program as a variable in a Jamfile?
209    </title>
210
211    <para>The <code>SHELL</code> builtin can be used for the purpose:
212<programlisting>
213local gtk_includes = [ SHELL "gtk-config --cflags" ] ;
214</programlisting>
215    </para>
216  </section>
217
218  <section>
219    <title>How to get the project-root location?
220    </title>
221
222    <para>You might want to use the location of the project-root in your
223      Jamfiles. To do it, you'd need to declare path constant in your
224      project-root.jam:
225<programlisting>
226path-constant TOP : . ;
227</programlisting>
228      After that, the <code>TOP</code> variable can be used in every Jamfile.
229    </para>
230  </section>
231
232  <section>
233    <title>How to change compilation flags for one file?
234    </title>
235
236    <para>If one file must be compiled with special options, you need to
237      explicitly declare an <code>obj</code> target for that file and then use
238      that target in your <code>exe</code> or <code>lib</code> target:
239<programlisting>
240exe a : a.cpp b ;
241obj b : b.cpp : &lt;optimization&gt;off ;
242</programlisting>
243      Of course you can use other properties, for example to specify specific
244      compiler options:
245<programlisting>
246exe a : a.cpp b ;
247obj b : b.cpp : &lt;cflags&gt;-g ;
248</programlisting>
249      You can also use <link linkend="bbv2.tutorial.conditions">conditional
250      properties</link> for finer control:
251<programlisting>
252exe a : a.cpp b ;
253obj b : b.cpp : &lt;variant&gt;release:&lt;optimization&gt;off ;
254</programlisting>
255
256    </para>
257  </section>
258
259  <section id="bbv2.faq.dll-path">
260    <title>Why are the <code>dll-path</code> and
261    <code>hardcode-dll-paths</code> properties useful?
262    </title>
263
264    <para>(This entry is specific to Unix system.)Before answering the
265      questions, let's recall a few points about shared libraries. Shared
266      libraries can be used by several applications, or other libraries,
267      without phisycally including the library in the application. This can
268      greatly decrease the total size of applications. It's also possible to
269      upgrade a shared library when the application is already
270      installed. Finally, shared linking can be faster.
271    </para>
272
273    <para>However, the shared library must be found when the application is
274      started. The dynamic linker will search in a system-defined list of
275      paths, load the library and resolve the symbols. Which means that you
276      should either change the system-defined list, given by the
277      <envar>LD_LIBRARY_PATH</envar> environment variable, or install the
278      libraries to a system location. This can be inconvenient when
279      developing, since the libraries are not yet ready to be installed, and
280      cluttering system paths is undesirable. Luckily, on Unix there's another
281      way.
282    </para>
283
284    <para>An executable can include a list of additional library paths, which
285      will be searched before system paths. This is excellent for development,
286      because the build system knows the paths to all libraries and can include
287      them in executables. That's done when the <code>hardcode-dll-paths</code>
288      feature has the <literal>true</literal> value, which is the
289      default. When the executables should be installed, the story is
290      different.
291    </para>
292
293    <para>
294      Obviously, installed executable should not hardcode paths to your
295      development tree. (The <code>stage</code> rule explicitly disables the
296      <code>hardcode-dll-paths</code> feature for that reason.) However, you
297      can use the <code>dll-path</code> feature to add explicit paths
298      manually. For example:
299<programlisting>
300stage installed : application : &lt;dll-path&gt;/usr/lib/snake
301                                &lt;location&gt;/usr/bin ;         
302</programlisting>
303      will allow the application to find libraries placed to
304      <filename>/usr/lib/snake</filename>.
305    </para>
306
307    <para>If you install libraries to a nonstandard location and add an
308      explicit path, you get more control over libraries which will be used. A
309      library of the same name in a system location will not be inadvertently
310      used.  If you install libraries to a system location and do not add any
311      paths, the system administrator will have more control. Each library can
312      be individually upgraded, and all applications will use the new library.
313    </para>
314
315    <para>Which approach is best depends on your situation. If the libraries
316      are relatively standalone and can be used by third party applications,
317      they should be installed in the system location. If you have lots of
318      libraries which can be used only by your application, it makes sense to
319      install it to a nonstandard directory and add an explicit path, like the
320      example above shows. Please also note that guidelines for different
321      systems differ in this respect. The Debian guidelines prohibit any
322      additional search paths, and Solaris guidelines suggest that they should
323      always be used.
324    </para>
325     
326  </section>
327
328  <section id="bbv2.recipies.site-config">
329    <title>Targets in site-config.jam</title>
330
331    <para>It is desirable to declare standard libraries available on a
332      given system. Putting target declaration in Jamfile is not really
333      good, since locations of the libraries can vary. The solution is
334      to put the following to site-config.jam.</para>   
335<programlisting>
336import project ;
337project.initialize $(__name__) ;
338project site-config ;
339lib zlib : : &lt;name&gt;z ;
340</programlisting>
341
342    <para>The second line allows this module to act as project. The
343      third line gives id to this project &#x2014; it really has no location
344      and cannot be used otherwise. The fourth line just declares a
345      target. Now, one can write:
346<programlisting>
347exe hello : hello.cpp /site-config//zlib ;
348</programlisting>
349      in any Jamfile.</para>
350
351  </section>
352
353  <section id="bbv2.faq.header-only-libraries">
354    <title>Header-only libraries</title>
355
356    <para>In modern C++, libraries often consist of just header files, without
357    any source files to compile. To use such libraries, you need to add proper
358    includes and, maybe, defines, to your project. But with large number of
359    external libraries it becomes problematic to remember which libraries are
360    header only, and which are "real" ones. However, with Boost.Build a
361    header-only library can be declared as Boost.Build target and all
362    dependents can use such library without remebering if it's header-only or not.
363    </para>
364
365    <para>Header-only libraries are declared using the <code>alias</code> rule,
366    that specifies only usage requirements, for example:
367<programlisting>
368alias mylib
369    : # no sources
370    : # no build requirements
371    : # no default build
372    : &lt;include&gt;whatever
373    ;
374</programlisting>
375    The includes specified in usage requirements of <code>mylib</code> are
376    automatically added to build properties of all dependents. The dependents
377    need not care if <code>mylib</code> is header-only or not, and it's possible
378    to later make <code>mylib</code> into a regular compiled library.
379    </para>
380
381    <para>
382      If you already have proper usage requirements declared for project where
383      header-only library is defined, you don't need to duplicate them for
384      the <code>alias</code> target:
385<programlisting>
386project my : usage-requirements &lt;include&gt;whatever ;
387alias mylib ;
388</programlisting>     
389    </para>
390
391  </section>
392
393   
394  </chapter>
395<!--
396     Local Variables:
397     mode: nxml
398     sgml-indent-data: t     
399     sgml-parent-document: ("userman.xml" "chapter")
400     sgml-set-face: t
401     End:
402-->
Note: See TracBrowser for help on using the repository browser.