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