• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[[bbv2.tutorial]]
2= Tutorial
3
4This section will guide you though the most basic features of
5B2. We will start with the “Hello, world” example, learn how to
6use libraries, and finish with testing and installing features.
7
8[[bbv2.tutorial.hello]]
9== Hello, world
10
11The simplest project that B2 can construct is stored in
12`example/hello/` directory. The project is described by a file called
13`Jamfile` that contains:
14
15[source]
16----
17exe hello : hello.cpp ;
18----
19
20Even with this simple setup, you can do some interesting things. First
21of all, just invoking `b2` will build the `hello` executable by compiling
22and linking `hello.cpp`. By default, the debug variant is built. Now, to
23build the release variant of `hello`, invoke
24
25[source,shell]
26----
27b2 release
28----
29
30Note that the debug and release variants are created in different
31directories, so you can switch between variants or even build multiple
32variants at once, without any unnecessary recompilation. Let us extend
33the example by adding another line to our project's `Jamfile`:
34
35[source]
36----
37exe hello2 : hello.cpp ;
38----
39
40Now let us build both the debug and release variants of our project
41again:
42
43[source,shell]
44----
45b2 debug release
46----
47
48Note that two variants of `hello2` are linked. Since we have already
49built both variants of `hello`, hello.cpp will not be recompiled;
50instead the existing object files will just be linked into the
51corresponding variants of `hello2`. Now let us remove all the built
52products:
53
54[source,shell]
55----
56b2 --clean debug release
57----
58
59It is also possible to build or clean specific targets. The following
60two commands, respectively, build or clean only the debug version of
61`hello2`.
62
63[source,shell]
64----
65b2 hello2
66b2 --clean hello2
67----
68
69[[bbv2.tutorial.properties]]
70== Properties
71
72To represent aspects of target configuration such as debug and release
73variants, or single- and multi-threaded builds portably, B2
74uses _features_ with associated _values_. For example, the `debug-symbols`
75feature can have a value of `on` or `off`. A _property_ is just a
76(feature, value) pair. When a user initiates a build, B2
77automatically translates the requested properties into appropriate
78command-line flags for invoking toolset components like compilers and
79linkers.
80
81There are many built-in features that can be combined to produce
82arbitrary build configurations. The following command builds the
83project's `release` variant with inlining disabled and debug symbols
84enabled:
85
86[source,shell]
87----
88b2 release inlining=off debug-symbols=on
89----
90
91Properties on the command-line are specified with the syntax:
92
93----
94feature-name=feature-value
95----
96
97The `release` and `debug` that we have seen in `b2` invocations are just
98a shorthand way to specify values of the `variant` feature. For example,
99the command above could also have been written this way:
100
101[source,shell]
102----
103b2 variant=release inlining=off debug-symbols=on
104----
105
106`variant` is so commonly-used that it has been given special status as
107an _implicit_ feature—B2 will deduce its identity just from the
108name of one of its values.
109
110A complete description of features can be found in
111link:#bbv2.reference.features[the section called “Features and properties”].
112
113[[bbv2.tutorial.properties.requirements]]
114=== Build Requests and Target Requirements
115
116The set of properties specified on the command line constitutes a _build
117request_—a description of the desired properties for building the
118requested targets (or, if no targets were explicitly requested, the
119project in the current directory). The _actual_ properties used for
120building targets are typically a combination of the build request and
121properties derived from the project's `Jamfile` (and its other Jamfiles,
122as described in
123link:#bbv2.tutorial.hierarchy[the section called “Project Hierarchies”]).
124For example, the locations of `#include`d header files are normally not
125specified on the command-line, but described in Jamfiles as _target
126requirements_ and automatically combined with the build request for those
127targets. Multi-threaded compilation is another example of a typical
128target requirement. The Jamfile fragment below illustrates how these
129requirements might be specified.
130
131[source]
132----
133exe hello
134    : hello.cpp
135    : <include>boost <threading>multi
136    ;
137----
138
139When `hello` is built, the two requirements specified above will always
140be present. If the build request given on the `b2` command-line
141explicitly contradicts a target's requirements, the target requirements
142usually override (or, in the case of “free” features like
143`<include>`, footnote:[See
144link:#bbv2.reference.features.attributes[the section called “Feature Attributes”]]
145augment) the build request.
146
147TIP: The value of the `<include>` feature is relative to the location of
148`Jamfile` where it is used.
149
150[[bbv2.tutorial.properties.project_attributes]]
151=== Project Attributes
152
153If we want the same requirements for our other target, `hello2`, we
154could simply duplicate them. However, as projects grow, that approach
155leads to a great deal of repeated boilerplate in Jamfiles. Fortunately,
156there's a better way. Each project can specify a set of _attributes_,
157including requirements:
158
159[source]
160----
161project
162    : requirements <include>/home/ghost/Work/boost <threading>multi
163    ;
164
165exe hello : hello.cpp ;
166exe hello2 : hello.cpp ;
167----
168
169The effect would be as if we specified the same requirement for both
170`hello` and `hello2`.
171
172[[bbv2.tutorial.hierarchy]]
173== Project Hierarchies
174
175So far we have only considered examples with one project, with one
176user-written `Jamfile` file. A typical large codebase would
177be composed of many projects organized into a tree. The top of the tree
178is called the _project root_. Every subproject is defined by a file called
179`Jamfile` in a descendant directory of the project root. The parent
180project of a subproject is defined by the nearest Jamfile
181file in an ancestor directory. For example, in the following directory
182layout:
183
184....
185top/
186  |
187  +-- Jamfile
188  |
189  +-- app/
190  |    |
191  |    +-- Jamfile
192  |    `-- app.cpp
193  |
194  `-- util/
195       |
196       +-- foo/
197       .    |
198       .    +-- Jamfile
199       .    `-- bar.cpp
200....
201
202the project root is `top/`. The projects in `top/app/` and
203`top/util/foo/` are immediate children of the root project.
204
205NOTE: When we refer to a “Jamfile,” set in normal type, we mean a file called
206either `Jamfile` or `Jamroot`. When we need to be more specific, the
207filename will be set as “`Jamfile`” or “`Jamroot`.”
208
209Projects inherit all attributes (such as requirements) from their
210parents. Inherited requirements are combined with any requirements
211specified by the subproject. For example, if `top/Jamfile` has
212
213[source]
214----
215<include>/home/ghost/local
216----
217
218in its requirements, then all of its sub-projects will have it in their
219requirements, too. Of course, any project can add include paths to those
220specified by its parents. footnote:[Many features will be overridden,
221rather than added-to, in sub-projects See
222link:#bbv2.reference.features.attributes[the section called “Feature Attributes”] for more information] More
223details can be found in link:#bbv2.overview.projects[the section called “Projects”].
224
225Invoking `b2` without explicitly specifying any targets on the command
226line builds the project rooted in the current directory. Building a
227project does not automatically cause its sub-projects to be built unless
228the parent project's Jamfile explicitly requests it. In our example,
229`top/Jamfile` might contain:
230
231[source]
232----
233build-project app ;
234----
235
236which would cause the project in `top/app/` to be built whenever the
237project in `top/` is built. However, targets in `top/util/foo/` will be
238built only if they are needed by targets in `top/` or `top/app/`.
239
240[[bbv2.tutorial.libs]]
241== Dependent Targets
242
243When building a target `X` that depends on first building another target
244`Y` (such as a library that must be linked with X), `Y` is called a
245_dependency_ of `X` and `X` is termed a _dependent_ of `Y`.
246
247To get a feeling of target dependencies, let's continue the above
248example and see how `top/app/Jamfile` can use libraries from
249`top/util/foo`. If `top/util/foo/Jamfile` contains
250
251[source]
252----
253lib bar : bar.cpp ;
254----
255
256then to use this library in `top/app/Jamfile`, we can write:
257
258[source]
259----
260exe app : app.cpp ../util/foo//bar ;
261----
262
263While `app.cpp` refers to a regular source file, `../util/foo//bar` is a
264reference to another target: a library `bar` declared in the Jamfile at
265`../util/foo`.
266
267TIP: Some other build system have special syntax for listing dependent
268libraries, for example `LIBS` variable. In B2, you just add the
269library to the list of sources.
270
271Suppose we build `app` with:
272
273[source,shell]
274----
275b2 app optimization=full define=USE_ASM
276----
277
278Which properties will be used to build `foo`? The answer is that some
279features are _propagated_ — B2 attempts to use dependencies with
280the same value of propagated features. The `<optimization>` feature is
281propagated, so both `app` and `foo` will be compiled with full
282optimization. But `<define>` is not propagated: its value will be added
283as-is to the compiler flags for `a.cpp`, but won't affect `foo`.
284
285Let's improve this project further. The library probably has some
286headers that must be used when compiling `app.cpp`. We could manually
287add the necessary `#include` paths to `app`'s requirements as values of
288the `<include>  ` feature, but then this work will be repeated for all
289programs that use `foo`. A better solution is to modify
290`util/foo/Jamfile` in this way:
291
292[source]
293----
294project
295    : usage-requirements <include>.
296    ;
297
298lib foo : foo.cpp ;
299----
300
301Usage requirements are applied not to the target being declared but to
302its dependents. In this case, `<include>.` will be applied to all
303targets that directly depend on `foo`.
304
305Another improvement is using symbolic identifiers to refer to the
306library, as opposed to `Jamfile` location. In a large project, a library
307can be used by many targets, and if they all use `Jamfile` location, a change
308in directory organization entails much work.
309The solution is to use project ids—symbolic names not tied to directory
310layout. First, we need to assign a project id by adding this code to
311`Jamfile`:
312
313[source]
314----
315use-project /library-example/foo : util/foo ;
316----
317
318Second, we modify `app/Jamfile` to use the project id:
319
320[source]
321----
322exe app : app.cpp /library-example/foo//bar ;
323----
324
325The `/library-example/foo//bar` syntax is used to refer to the target
326`bar` in the project with id `/library-example/foo`. We've achieved our
327goal—if the library is moved to a different directory, only `top/Jamfile`
328must be modified. Note that project ids are global—two Jamfiles
329are not allowed to assign the same project id to different directories.
330
331[TIP]
332====
333If you want all applications in some project to link to a certain
334library, you can avoid having to specify directly the sources of every
335target by using the `<library>` property. For example, if
336`/boost/filesystem//fs` should be linked to all applications in your
337project, you can add `<library>/boost/filesystem//fs` to the project's
338requirements, like this:
339
340[source]
341----
342project
343   : requirements <library>/boost/filesystem//fs
344   ;
345----
346====
347
348
349[[bbv2.tutorial.linkage]]
350== Static and shared libraries
351
352Libraries can be either _static_, which means they are included in
353executable files that use them, or _shared_ (a.k.a. _dynamic_), which
354are only referred to from executables, and must be available at run
355time. B2 can create and use both kinds.
356
357The kind of library produced from a `lib` target is determined by the
358value of the `link` feature. Default value is `shared`, and to build a
359static library, the value should be `static`. You can request a static
360build either on the command line:
361
362[source,shell]
363----
364b2 link=static
365----
366
367or in the library's requirements:
368
369[source]
370----
371lib l : l.cpp : <link>static ;
372----
373
374We can also use the `<link>` property to express linking requirements on
375a per-target basis. For example, if a particular executable can be
376correctly built only with the static version of a library, we can
377qualify the executable's link:#bbv2.reference.targets.references[target
378reference] to the library as follows:
379
380[source]
381----
382exe important : main.cpp helpers/<link>static ;
383----
384
385No matter what arguments are specified on the `b2` command line,
386`important` will only be linked with the static version of `helpers`.
387
388Specifying properties in target references is especially useful if you
389use a library defined in some other project (one you can't change) but
390you still want static (or dynamic) linking to that library in all cases.
391If that library is used by many targets, you _could_ use target
392references everywhere:
393
394[source]
395----
396exe e1 : e1.cpp /other_project//bar/<link>static ;
397exe e10 : e10.cpp /other_project//bar/<link>static ;
398----
399
400but that's far from being convenient. A better approach is to introduce
401a level of indirection. Create a local `alias` target that refers to the
402static (or dynamic) version of `foo`:
403
404[source]
405----
406alias foo : /other_project//bar/<link>static ;
407exe e1 : e1.cpp foo ;
408exe e10 : e10.cpp foo ;
409----
410
411The link:#bbv2.tasks.alias[alias] rule is specifically used to rename a
412reference to a target and possibly change the properties.
413
414[TIP]
415====
416When one library uses another, you put the second library in the source
417list of the first. For example:
418
419[source]
420----
421lib utils : utils.cpp /boost/filesystem//fs ;
422lib core : core.cpp utils ;
423exe app : app.cpp core ;
424----
425
426This works no matter what kind of linking is used. When `core` is built as a
427shared library, links `utils` directly into it. Static libraries can't link
428to other libraries, so when `core` is built as a static library, its
429dependency on `utils` is passed along to `core`'s dependents, causing `app`
430to be linked with both `core` and `utils`.
431====
432
433NOTE: (Note for non-UNIX system). Typically, shared libraries must be
434installed to a directory in the dynamic linker's search path. Otherwise,
435applications that use shared libraries can't be started. On Windows, the
436dynamic linker's search path is given by the `PATH` environment variable.
437This restriction is lifted when you use B2 testing
438facilities—the `PATH` variable will be automatically adjusted before
439running the executable.
440
441[[bbv2.tutorial.conditions]]
442== Conditions and alternatives
443
444Sometimes, particular relationships need to be maintained among a
445target's build properties. For example, you might want to set specific
446`#define` when a library is built as shared, or when a target's
447`release` variant is built. This can be achieved using _conditional
448requirements_.
449
450[source]
451----
452lib network : network.cpp
453    : <link>shared:<define>NETWORK_LIB_SHARED
454      <variant>release:<define>EXTRA_FAST
455    ;
456----
457
458In the example above, whenever `network` is built with `<link>shared`,
459`<define>NETWORK_LIB_SHARED` will be in its properties, too. Also, whenever
460its release variant is built, `<define>EXTRA_FAST` will appear in its
461properties.
462
463Sometimes the ways a target is built are so different that describing
464them using conditional requirements would be hard. For example, imagine
465that a library actually uses different source files depending on the
466toolset used to build it. We can express this situation using target
467_alternatives_:
468
469[source]
470----
471lib demangler : dummy_demangler.cpp ;                # <1>
472lib demangler : demangler_gcc.cpp : <toolset>gcc ;   # <2>
473lib demangler : demangler_msvc.cpp : <toolset>msvc ; # <3>
474----
475
476When building `demangler`, B2 will compare requirements for
477each alternative with build properties to find the best match. For
478example, when building with `<toolset>gcc` alternative *(2)*, will be
479selected, and when building with `<toolset>msvc` alternative *(3)* will be
480selected. In all other cases, the most generic alternative *(1)* will be
481built.
482
483[[bbv2.tutorial.prebuilt]]
484== Prebuilt targets
485
486To link to libraries whose build instructions aren't given in a Jamfile,
487you need to create `lib` targets with an appropriate `file` property.
488Target alternatives can be used to associate multiple library files with
489a single conceptual target. For example:
490
491[source]
492----
493# util/lib2/Jamfile
494lib lib2
495    :
496    : <file>lib2_release.a <variant>release
497    ;
498
499lib lib2
500    :
501    : <file>lib2_debug.a <variant>debug
502    ;
503----
504
505This example defines two alternatives for `lib2`, and for each one names
506a prebuilt file. Naturally, there are no sources. Instead, the `<file>`
507feature is used to specify the file name.
508
509Once a prebuilt target has been declared, it can be used just like any
510other target:
511
512[source]
513----
514exe app : app.cpp ../util/lib2//lib2 ;
515----
516
517As with any target, the alternative selected depends on the properties
518propagated from `lib2`'s dependents. If we build the release and debug
519versions of `app` it will be linked with `lib2_release.a` and
520`lib2_debug.a`, respectively.
521
522System libraries — those that are automatically found by the toolset by
523searching through some set of predetermined paths — should be declared
524almost like regular ones:
525
526[source]
527----
528lib pythonlib : : <name>python22 ;
529----
530
531We again don't specify any sources, but give a `name` that should be
532passed to the compiler. If the gcc toolset were used to link an
533executable target to `pythonlib`, `-lpython22` would appear in the
534command line (other compilers may use different options).
535
536We can also specify where the toolset should look for the library:
537
538[source]
539----
540lib pythonlib : : <name>python22 <search>/opt/lib ;
541----
542
543And, of course, target alternatives can be used in the usual way:
544
545[source]
546----
547lib pythonlib : : <name>python22 <variant>release ;
548lib pythonlib : : <name>python22_d <variant>debug ;
549----
550
551A more advanced use of prebuilt targets is described in
552link:#bbv2.recipes.site-config[the section called “Targets in
553site-config.jam”].
554