Library targets are created using the lib
rule, which
follows the common syntax
. For example:
lib helpers : helpers.cpp ;
This will define a library target named helpers
built from
the helpers.cpp
source file.
It can be either a static library or a shared library,
depending on the value of the <link> feature.
Library targets can represent:
Libraries that should be built from source, as in the example above.
Prebuilt libraries which already exist on the system.
Such libraries can be searched for by the tools using them (typically
with the linker's -l
option) or their paths can be
known in advance by the build system.
The syntax for prebuilt libraries is given below:
lib z : : <name>z <search>/home/ghost ; lib compress : : <file>/opt/libs/compress.a ;
The name
property specifies the name of the library
without the standard prefixes and suffixes. For example, depending
on the system, z
could refer to a file called
z.so, libz.a, or z.lib, etc. The search
feature
specifies paths in which to search for the library in addition
to the default compiler paths. search
can be specified
several times or it can be omitted, in which case only the default
compiler paths will be searched. The file
property
specifies the file location.
The difference between using the file
feature and
using a combination of the name
and search
features is that file
is more precise.
The value of the search
feature is just added to the
linker search path. When linking to multiple libraries,
the paths specified by search
are combined without
regard to which lib
target each path came from.
Thus, given
lib a : : <name>a <search>/pool/release ; lib b : : <name>b <search>/pool/debug ;
If /pool/release/a.so, /pool/release/b.so, /pool/debug/a.so,
and /pool/release/b.so all exist, the linker will probably
take both a
and b
from the same
directory, instead of finding a
in /pool/release
and b
in /pool/debug. If you need to distinguish
between multiple libraries with the same name, it's safer
to use file
.
For convenience, the following syntax is allowed:
lib z ; lib gui db aux ;
which has exactly the same effect as:
lib z : : <name>z ; lib gui : : <name>gui ; lib db : : <name>db ; lib aux : : <name>aux ;
When a library references another library you should put that other library in its list of sources. This will do the right thing in all cases. For portability, you should specify library dependencies even for searched and prebuilt libraries, othewise, static linking on Unix will not work. For example:
lib z ; lib png : z : <name>png ;
When a library has a shared library as a source, or a static library has another static library as a source then any target linking to the first library with automatically link to its source library as well.
On the other hand, when a shared library has a static library as a source then the first library will be built so that it completely includes the second one.
If you do not want a shared library to include all the libraries specified in its sources (especially statically linked ones), you would need to use the following:
lib b : a.cpp ; lib a : a.cpp : <use>b : : <library>b ;
This specifies that library a
uses library b
,
and causes all executables that link to a
to link to
b
also. In this case, even for shared linking, the
a
library will not refer to b
.
Usage requirements are often
very useful for defining library targets. For example, imagine that
you want you build a helpers
library and its interface is
described in its helpers.hpp
header file located in the same
directory as the helpers.cpp
source file. Then you could add
the following to the Jamfile located in that same directory:
lib helpers : helpers.cpp : : : <include>. ;
which would automatically add the directory where the target has been
defined (and where the library's header file is located) to the compiler's
include path for all targets using the helpers
library. This
feature greatly simplifies Jamfiles.