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