Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/tools/build/v2/doc/src/faq.xml @ 12

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

added boost

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