]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | <!DOCTYPE chapter 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 id="bbv2.faq.featurevalue"> | |
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 | |
16 | run of Boost.Build, any given main target can be | |
17 | built with several property sets. For example, user can request two build | |
18 | variants on the command line. Or one library is built as shared when used | |
19 | from one application, and as static when used from another. Each Jamfile | |
20 | is read only once so generally there is no single value of a feature you | |
21 | can access in Jamfile. | |
22 | </para> | |
23 | ||
24 | <para> | |
25 | A feature has a specific value only when building a target, and there are | |
26 | two ways you can use that value: | |
27 | </para> | |
28 | ||
29 | <itemizedlist> | |
30 | <listitem> | |
31 | <simpara> | |
32 | Use conditional requirements or indirect conditional requirements. See | |
33 | <xref linkend="bbv2.overview.targets.requirements.conditional"/>. | |
34 | </simpara> | |
35 | </listitem> | |
36 | <listitem> | |
37 | Define a custom generator and a custom main target type. The custom | |
38 | generator can do arbitrary processing or properties. See the <xref | |
39 | linkend="bbv2.extender">extender manual</xref>. | |
40 | </listitem> | |
41 | </itemizedlist> | |
42 | </section> | |
43 | ||
44 | <section id="bbv2.faq.duplicate"> | |
45 | <title> | |
46 | I am getting a "Duplicate name of actual target" error. What does that | |
47 | mean? | |
48 | </title> | |
49 | ||
50 | <para> | |
51 | The most likely case is that you are trying to compile the same file | |
52 | twice, with almost the same, but differing properties. For example: | |
53 | <programlisting> | |
54 | exe a : a.cpp : <include>/usr/local/include ; | |
55 | exe b : a.cpp ; | |
56 | </programlisting> | |
57 | </para> | |
58 | ||
59 | <para> | |
60 | The above snippet requires two different compilations of | |
61 | <code>a.cpp</code>, which differ only in their <literal>include</literal> | |
62 | property. Since the <literal>include</literal> feature is declared as | |
63 | <literal>free</literal> Boost.Build does not create a separate build | |
64 | directory for each of its values and those two builds would both produce | |
65 | object files generated in the same build directory. Ignoring this and | |
66 | compiling the file only once would be dangerous as different includes | |
67 | could potentially cause completely different code to be compiled. | |
68 | </para> | |
69 | ||
70 | <para> | |
71 | To solve this issue, you need to decide if the file should be compiled | |
72 | once or twice. | |
73 | </para> | |
74 | ||
75 | <orderedlist> | |
76 | <listitem> | |
77 | <para> | |
78 | To compile the file only once, make sure that properties are the same | |
79 | for both target requests: | |
80 | <programlisting> | |
81 | exe a : a.cpp : <include>/usr/local/include ; | |
82 | exe b : a.cpp : <include>/usr/local/include ; | |
83 | </programlisting> | |
84 | or: | |
85 | <programlisting> | |
86 | alias a-with-include : a.cpp : <include>/usr/local/include ; | |
87 | exe a : a-with-include ; | |
88 | exe b : a-with-include ; | |
89 | </programlisting> | |
90 | or if you want the <literal>includes</literal> property not to affect | |
91 | how any other sources added for the built <code>a</code> and | |
92 | <code>b</code> executables would be compiled: | |
93 | <programlisting> | |
94 | obj a-obj : a.cpp : <include>/usr/local/include ; | |
95 | exe a : a-obj ; | |
96 | exe b : a-obj ; | |
97 | </programlisting> | |
98 | </para> | |
99 | <para> | |
100 | Note that in both of these cases the <literal>include</literal> | |
101 | property will be applied only for building these object files and not | |
102 | any other sources that might be added for targets <code>a</code> and | |
103 | <code>b</code>. | |
104 | </para> | |
105 | </listitem> | |
106 | ||
107 | <listitem> | |
108 | <para> | |
109 | To compile the file twice, you can tell Boost.Build to compile it to | |
110 | two separate object files like so: | |
111 | <programlisting> | |
112 | obj a_obj : a.cpp : <include>/usr/local/include ; | |
113 | obj b_obj : a.cpp ; | |
114 | exe a : a_obj ; | |
115 | exe b : b_obj ; | |
116 | </programlisting> | |
117 | or you can make the object file targets local to the main target: | |
118 | <programlisting> | |
119 | exe a : [ obj a_obj : a.cpp : <include>/usr/local/include ] ; | |
120 | exe b : [ obj a_obj : a.cpp ] ; | |
121 | </programlisting> | |
122 | which will cause Boost.Build to actually change the generated object | |
123 | file names a bit for you and thus avoid any conflicts. | |
124 | </para> | |
125 | <para> | |
126 | Note that in both of these cases the <literal>include</literal> | |
127 | property will be applied only for building these object files and not | |
128 | any other sources that might be added for targets <code>a</code> and | |
129 | <code>b</code>. | |
130 | </para> | |
131 | </listitem> | |
132 | </orderedlist> | |
133 | ||
134 | <para> | |
135 | A good question is why Boost.Build can not use some of the above | |
136 | approaches automatically. The problem is that such magic would only help | |
137 | in half of the cases, while in the other half it would be silently doing | |
138 | the wrong thing. It is simpler and safer to ask the user to clarify his | |
139 | intention in such cases. | |
140 | </para> | |
141 | </section> | |
142 | ||
143 | <section id="bbv2.faq.envar"> | |
144 | <title> | |
145 | Accessing environment variables | |
146 | </title> | |
147 | ||
148 | <para> | |
149 | Many users would like to use environment variables in Jamfiles, for | |
150 | example, to control the location of external libraries. In many cases it | |
151 | is better to declare those external libraries in the site-config.jam file, | |
152 | as documented in the <link linkend="bbv2.recipies.site-config">recipes | |
153 | section</link>. However, if the users already have the environment | |
154 | variables set up, it may not be convenient for them to set up their | |
155 | site-config.jam files as well and using the environment variables might be | |
156 | reasonable. | |
157 | </para> | |
158 | ||
159 | <para> | |
160 | Boost.Jam automatically imports all environment variables into its | |
161 | built-in .ENVIRON module so user can read them from there directly or by | |
162 | using the helper os.environ rule. For example: | |
163 | <programlisting> | |
164 | import os ; | |
165 | local unga-unga = [ os.environ UNGA_UNGA ] ; | |
166 | ECHO $(unga-unga) ; | |
167 | </programlisting> | |
168 | or a bit more realistic: | |
169 | <programlisting> | |
170 | import os ; | |
171 | local SOME_LIBRARY_PATH = [ os.environ SOME_LIBRARY_PATH ] ; | |
172 | exe a : a.cpp : <include>$(SOME_LIBRARY_PATH) ; | |
173 | </programlisting> | |
174 | </para> | |
175 | </section> | |
176 | ||
177 | <section id="bbv2.faq.proporder"> | |
178 | <title> | |
179 | How to control properties order? | |
180 | </title> | |
181 | ||
182 | <para> | |
183 | For internal reasons, Boost.Build sorts all the properties alphabetically. | |
184 | This means that if you write: | |
185 | <programlisting> | |
186 | exe a : a.cpp : <include>b <include>a ; | |
187 | </programlisting> | |
188 | then the command line with first mention the <code>a</code> include | |
189 | directory, and then <code>b</code>, even though they are specified in the | |
190 | opposite order. In most cases, the user does not care. But sometimes the | |
191 | order of includes, or other properties, is important. For such cases, a | |
192 | special syntax is provided: | |
193 | <programlisting> | |
194 | exe a : a.cpp : <include>a&&b ; | |
195 | </programlisting> | |
196 | </para> | |
197 | ||
198 | <para> | |
199 | The <code>&&</code> symbols separate property values and specify | |
200 | that their order should be preserved. You are advised to use this feature | |
201 | only when the order of properties really matters and not as a convenient | |
202 | shortcut. Using it everywhere might negatively affect performance. | |
203 | </para> | |
204 | </section> | |
205 | ||
206 | <section id="bbv2.faq.liborder"> | |
207 | <title> | |
208 | How to control the library linking order on Unix? | |
209 | </title> | |
210 | ||
211 | <para> | |
212 | On Unix-like operating systems, the order in which static libraries are | |
213 | specified when invoking the linker is important, because by default, the | |
214 | linker uses one pass though the libraries list. Passing the libraries in | |
215 | the incorrect order will lead to a link error. Further, this behaviour is | |
216 | often used to make one library override symbols from another. So, | |
217 | sometimes it is necessary to force specific library linking order. | |
218 | </para> | |
219 | ||
220 | <para> | |
221 | Boost.Build tries to automatically compute the right order. The primary | |
222 | rule is that if library <code>a</code> "uses" library <code>b</code>, then | |
223 | library <code>a</code> will appear on the command line before library | |
224 | <code>b</code>. Library <code>a</code> is considered to use <code>b</code> | |
225 | if <code>b</code> is present either in the <code>a</code> library's | |
226 | sources or its usage is listed in its requirements. To explicitly specify | |
227 | the <literal>use</literal> relationship one can use the | |
228 | <literal><use></literal> feature. For example, both of the following | |
229 | lines will cause <code>a</code> to appear before <code>b</code> on the | |
230 | command line: | |
231 | <programlisting> | |
232 | lib a : a.cpp b ; | |
233 | lib a : a.cpp : <use>b ; | |
234 | </programlisting> | |
235 | </para> | |
236 | ||
237 | <para> | |
238 | The same approach works for searched libraries as well: | |
239 | <programlisting> | |
240 | lib z ; | |
241 | lib png : : <use>z ; | |
242 | exe viewer : viewer png z ; | |
243 | </programlisting> | |
244 | </para> | |
245 | </section> | |
246 | ||
247 | <section id="bbv2.faq.external"> | |
248 | <title> | |
249 | Can I get capture external program output using a Boost.Jam variable? | |
250 | </title> | |
251 | ||
252 | <para> | |
253 | The <literal>SHELL</literal> builtin rule may be used for this purpose: | |
254 | <programlisting> | |
255 | local gtk_includes = [ SHELL "gtk-config --cflags" ] ; | |
256 | </programlisting> | |
257 | </para> | |
258 | </section> | |
259 | ||
260 | <section id="bbv2.faq.projectroot"> | |
261 | <title> | |
262 | How to get the project root (a.k.a. Jamroot) location? | |
263 | </title> | |
264 | ||
265 | <para> | |
266 | You might want to use your project's root location in your Jamfiles. To | |
267 | access it just declare a path constant in your Jamroot.jam file using: | |
268 | <programlisting> | |
269 | path-constant TOP : . ; | |
270 | </programlisting> | |
271 | After that, the <code>TOP</code> variable can be used in every Jamfile. | |
272 | </para> | |
273 | </section> | |
274 | ||
275 | <section id="bbv2.faq.flags"> | |
276 | <title> | |
277 | How to change compilation flags for one file? | |
278 | </title> | |
279 | ||
280 | <para> | |
281 | If one file must be compiled with special options, you need to explicitly | |
282 | declare an <code>obj</code> target for that file and then use that target | |
283 | in your <code>exe</code> or <code>lib</code> target: | |
284 | <programlisting> | |
285 | exe a : a.cpp b ; | |
286 | obj b : b.cpp : <optimization>off ; | |
287 | </programlisting> | |
288 | Of course you can use other properties, for example to specify specific | |
289 | C/C++ compiler options: | |
290 | <programlisting> | |
291 | exe a : a.cpp b ; | |
292 | obj b : b.cpp : <cflags>-g ; | |
293 | </programlisting> | |
294 | You can also use <link linkend="bbv2.tutorial.conditions">conditional | |
295 | properties</link> for finer control: | |
296 | <programlisting> | |
297 | exe a : a.cpp b ; | |
298 | obj b : b.cpp : <variant>release:<optimization>off ; | |
299 | </programlisting> | |
300 | </para> | |
301 | </section> | |
302 | ||
303 | <section id="bbv2.faq.dll-path"> | |
304 | <title> | |
305 | Why are the <literal>dll-path</literal> and <literal>hardcode-dll-paths | |
306 | </literal> properties useful? | |
307 | </title> | |
308 | <note> | |
309 | <para> | |
310 | This entry is specific to Unix systems. | |
311 | </para> | |
312 | </note> | |
313 | <para> | |
314 | Before answering the questions, let us recall a few points about shared | |
315 | libraries. Shared libraries can be used by several applications, or other | |
316 | libraries, without physically including the library in the application | |
317 | which can greatly decrease the total application size. It is also possible | |
318 | to upgrade a shared library when the application is already installed. | |
319 | </para> | |
320 | ||
321 | <para> | |
322 | However, in order for application depending on shared libraries to be | |
323 | started the OS may need to find the shared library when the application is | |
324 | started. The dynamic linker will search in a system-defined list of paths, | |
325 | load the library and resolve the symbols. Which means that you should | |
326 | either change the system-defined list, given by the <envar>LD_LIBRARY_PATH | |
327 | </envar> environment variable, or install the libraries to a system | |
328 | location. This can be inconvenient when developing, since the libraries | |
329 | are not yet ready to be installed, and cluttering system paths may be | |
330 | undesirable. Luckily, on Unix there is another way. | |
331 | </para> | |
332 | ||
333 | <para> | |
334 | An executable can include a list of additional library paths, which will | |
335 | be searched before system paths. This is excellent for development because | |
336 | the build system knows the paths to all libraries and can include them in | |
337 | the executables. That is done when the <literal>hardcode-dll-paths | |
338 | </literal> feature has the <literal>true</literal> value, which is the | |
339 | default. When the executables should be installed, the story is different. | |
340 | </para> | |
341 | ||
342 | <para> | |
343 | Obviously, installed executable should not contain hardcoded paths to your | |
344 | development tree. <!-- Make the following parenthised sentence a footer | |
345 | note --> (The <literal>install</literal> rule explicitly disables the | |
346 | <literal>hardcode-dll-paths</literal> feature for that reason.) However, | |
347 | you can use the <literal>dll-path</literal> feature to add explicit paths | |
348 | manually. For example: | |
349 | <programlisting> | |
350 | install installed : application : <dll-path>/usr/lib/snake | |
351 | <location>/usr/bin ; | |
352 | </programlisting> | |
353 | will allow the application to find libraries placed in the <filename> | |
354 | /usr/lib/snake</filename> directory. | |
355 | </para> | |
356 | ||
357 | <para> | |
358 | If you install libraries to a nonstandard location and add an explicit | |
359 | path, you get more control over libraries which will be used. A library of | |
360 | the same name in a system location will not be inadvertently used. If you | |
361 | install libraries to a system location and do not add any paths, the | |
362 | system administrator will have more control. Each library can be | |
363 | individually upgraded, and all applications will use the new library. | |
364 | </para> | |
365 | ||
366 | <para> | |
367 | Which approach is best depends on your situation. If the libraries are | |
368 | relatively standalone and can be used by third party applications, they | |
369 | should be installed in the system location. If you have lots of libraries | |
370 | which can be used only by your application, it makes sense to install them | |
371 | to a nonstandard directory and add an explicit path, like the example | |
372 | above shows. Please also note that guidelines for different systems differ | |
373 | in this respect. For example, the Debian GNU guidelines prohibit any | |
374 | additional search paths while Solaris guidelines suggest that they should | |
375 | always be used. | |
376 | </para> | |
377 | </section> | |
378 | ||
379 | <section id="bbv2.recipies.site-config"> | |
380 | <title>Targets in site-config.jam</title> | |
381 | ||
382 | <para> | |
383 | It is desirable to declare standard libraries available on a given system. | |
384 | Putting target declaration in a specific project's Jamfile is not really | |
385 | good, since locations of the libraries can vary between different | |
386 | development machines and then such declarations would need to be | |
387 | duplicated in different projects. The solution is to declare the targets | |
388 | in Boost.Build's <filename>site-config.jam</filename> configuration file: | |
389 | <programlisting> | |
390 | project site-config ; | |
391 | lib zlib : : <name>z ; | |
392 | </programlisting> | |
393 | </para> | |
394 | ||
395 | <para> | |
396 | Recall that both <filename>site-config.jam</filename> and | |
397 | <filename>user-config.jam</filename> are projects, and everything you can | |
398 | do in a Jamfile you can do in those files as well. So, you declare a | |
399 | project id and a target. Now, one can write: | |
400 | <programlisting> | |
401 | exe hello : hello.cpp /site-config//zlib ; | |
402 | </programlisting> | |
403 | in any Jamfile. | |
404 | </para> | |
405 | </section> | |
406 | ||
407 | <section id="bbv2.faq.header-only-libraries"> | |
408 | <title>Header-only libraries</title> | |
409 | ||
410 | <para> | |
411 | In modern C++, libraries often consist of just header files, without any | |
412 | source files to compile. To use such libraries, you need to add proper | |
413 | includes and possibly defines to your project. But with a large number of | |
414 | external libraries it becomes problematic to remember which libraries are | |
415 | header only, and which ones you have to link to. However, with Boost.Build | |
416 | a header-only library can be declared as Boost.Build target and all | |
417 | dependents can use such library without having to remember whether it is a | |
418 | header-only library or not. | |
419 | </para> | |
420 | ||
421 | <para> | |
422 | Header-only libraries may be declared using the <code>alias</code> rule, | |
423 | specifying their include path as a part of its usage requirements, for | |
424 | example: | |
425 | <programlisting> | |
426 | alias my-lib | |
427 | : # no sources | |
428 | : # no build requirements | |
429 | : # no default build | |
430 | : <include>whatever ; | |
431 | </programlisting> | |
432 | The includes specified in usage requirements of <code>my-lib</code> are | |
433 | automatically added to all of its dependants' build properties. The | |
434 | dependants need not care if <code>my-lib</code> is a header-only or not, | |
435 | and it is possible to later make <code>my-lib</code> into a regular | |
436 | compiled library without having to that its dependants' declarations. | |
437 | </para> | |
438 | ||
439 | <para> | |
440 | If you already have proper usage requirements declared for a project where | |
441 | a header-only library is defined, you do not need to duplicate them for | |
442 | the <code>alias</code> target: | |
443 | <programlisting> | |
444 | project my : usage-requirements <include>whatever ; | |
445 | alias mylib ; | |
446 | </programlisting> | |
447 | </para> | |
448 | </section> | |
449 | ||
450 | <section id="bbv2.faq.names"> | |
451 | <title> | |
452 | What is the difference between Boost.Build, | |
453 | <filename>b2</filename>, <filename>bjam</filename> and Perforce Jam? | |
454 | </title> | |
455 | ||
456 | <para> | |
457 | Boost.Build is the name of the complete build system. The executable that runs | |
458 | it is <filename>b2</filename>. That executable is written in C and implements | |
459 | performance-critical algorithms, like traversal of dependency graph and executing | |
460 | commands. It also implements an interpreted language used to implement the rest of | |
461 | Boost.Build. This executable is formally called "Boost.Build engine". | |
462 | </para> | |
463 | ||
464 | <para> | |
465 | The Boost.Build engine is derived from an earlier build tool called Perforce Jam. Originally, | |
466 | there were just minor changes, and the filename was <filename>bjam</filename>. Later on, | |
467 | with more and more changes, the similarity of names because a disservice to users, and as of | |
468 | Boost 1.47.0, the official name of the executable was changed to <filename>b2</filename>. | |
469 | A copy named <filename>bjam</filename> is still created for compatibility, | |
470 | but you are encouraged to use the new name in all cases. | |
471 | </para> | |
472 | ||
473 | <para> | |
474 | Perforce Jam was an important foundation, and we gratefully acknowledge its influence, | |
475 | but for users today, these tools share only some basics of the interpreted language. | |
476 | </para> | |
477 | ||
478 | </section> | |
479 | ||
480 | </chapter> | |
481 | ||
482 | <!-- | |
483 | Local Variables: | |
484 | mode: nxml | |
485 | sgml-indent-data: t | |
486 | sgml-parent-document: ("userman.xml" "chapter") | |
487 | sgml-set-face: t | |
488 | End: | |
489 | --> |