boost.png (6897 bytes) Home Libraries People FAQ More

PrevUpHomeNext

Builtin target types

Programs
Libraries
Alias
Installing
Testing

Programs

Programs are created using the exe rule, which follows the common syntax. For example:

exe hello : hello.cpp some_library.lib /some_project//library 
          : <threading>multi 
          ;

This will create an executable file from the sources -- in this case, one C++ file, one library file present in the same directory, and another library that is created by Boost.Build. Generally, sources can include C and C++ files, object files and libraries. Boost.Build will automatically try to convert targets of other types.

Tip

On Windows, if an application uses dynamic libraries, and both the application and the libraries are built by Boost.Build, its not possible to immediately run the application, because the PATH environment variable should include the path to the libraries. It means you have to either add the paths manually, or place the application and the libraries to the same directory, for example using the stage rule.

Libraries

Libraries are created using the lib rule, which follows the common syntax. For example:

lib helpers : helpers.cpp : <include>boost : : <include>. ;

In the most common case, the lib creates a library from the specified sources. Depending on the value of <link> feature the library will be either static or shared. There are two other cases. First is when the library is installed somewhere in compiler's search paths, and should be searched by the compiler (typically, using the -l option). The second case is where the library is available as a prebuilt file and the full path is known.

The syntax for these case is given below:

lib z : : <name>z <search>/home/ghost ;            
lib compress : : <file>/opt/libs/compress.a ;

The name property specifies the name that should be passed to the -l option, and the file property specifies the file location. The search feature specifies paths in which to search for the library. That feature can be specified several times, or it can be omitted, in which case only default compiler paths will be searched.

The difference between using the file feature as opposed to the name feature together with the search feature is that file is more precise. A specific file will be used. On the other hand, the search feature only adds a library path, and the name feature gives the basic name of the library. The search rules are specific to the linker. For example, given these definition:

lib a : : <variant>release <file>/pool/release/a.so ;
lib a : : <variant>debug <file>/pool/debug/a.so ;
lib b : : <variant>release <file>/pool/release/b.so ;
lib b : : <variant>debug <file>/pool/debug/b.so ;

It's possible to use release version of a and debug version of b. Had we used the name and search features, the linker would always pick either release or debug versions.

For convenience, the following syntax is allowed:

lib z ;
lib gui db aux ;

and is does exactly the same as:

lib z : : <name>z ;            
lib gui : : <name>gui ;            
lib db : : <name>db ;            
lib aux : : <name>aux ;            

When a library uses another library you should put that another library in the 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 won't work. For example:

lib z ;
lib png : z : <name>png ;

Note

When a library (say, a), that has another library, (say, b) is linked dynamically, the b library will be incorporated in a. (If b is dynamic library as well, then a will only refer to it, and not include any extra code.) When the a library is linked statically, Boost.Build will assure that all executables that link to a will also link to b.

One feature of Boost.Build that is very important for libraries is usage requirements. For example, if you write:

lib helpers : helpers.cpp : : : <include>. ;

then the compiler include path for all targets that use helpers will contain the directory where the target is defined.path to "helpers.cpp". The user only needs to add helpers to the list of sources, and needn't consider the requirements its use imposes on a dependent target. This feature greatly simplifies Jamfiles.

Note

If you don't want shared libraries to include all libraries that are specified in sources (especially statically linked ones), you'd need to use the following:

lib b : a.cpp ;
lib a : a.cpp : <use>b : : <library>b ;

This specifies that a uses b, and causes all executables that link to a also link to b. In this case, even for shared linking, the a library won't even refer to b.

Alias

The alias rule follows the common syntax. For example:

alias core : im reader writer ;

will build the sources and return the generated source targets without modification.

The alias rule is a convenience tool. If you often build the same group of targets at the same time, you can define an alias to save typing.

Another use of the alias rule is to change build properties. For example, if you always want static linking for a specific C++ Boost library, you can write the following:

alias threads : /boost/thread//boost_thread : <link>static ;

and use only the threads alias in your Jamfiles.

You can also specify usage requirements for the alias target. If you write the following:

alias header_only_library : : : :  <include>/usr/include/header_only_library ; 

then using header_only_library in sources will only add an include path. Also note that when there are some sources, their usage requirements are propagated, too. For example:

lib lib : lib.cpp : : : <include>. ;
alias lib_alias ; 
exe main : main.cpp lib_alias ;

will compile main.cpp with the additional include.

Installing

For installing a built target you should use the install rule, which follows the common syntax. For example:

install dist : hello helpers ;

will cause the targets hello and helpers to be moved to the dist directory, relative to Jamfile's directory. The directory can be changed with the location property:

install dist : hello helpers : <location>/usr/bin ;

While you can achieve the same effect by changing the target name to /usr/bin, using the location property is better, because it allows you to use a memnonic target name.

The location property is especially handy when the location is not fixed, but depends on build variant or environment variables:

install dist : hello helpers : <variant>release:<location>dist/release
                             <variant>debug:<location>dist/debug ;
install dist2 : hello helpers : <location>$(DIST) ;

See also conditional properties and environment variables

Specifying the names of all libraries to install can be boring. The install allows you to specify only the top-level executable targets to install, and automatically install all dependencies:

install dist : hello 
           : <install-dependencies>on <install-type>EXE
             <install-type>LIB
           ;

will find all targets that hello depends on, and install all of the which are either executables or libraries. More specifically, for each target, other targets that were specified as sources or as dependency properties, will be recursively found. One exception is that targets referred with the use feature are not considered, because that feature is typically used to refer to header-only libraries. If the set of target types is specified, only targets of that type will be installed, otherwise, all found target will be installed.

The alias rule can be used when targets must be installed into several directories:

install install : install-bin install-lib ;
install install-bin : applications : /usr/bin ;
install install-lib : helper : /usr/lib ;

Because the install rule just copies targets, most free features [6] have no effect when used in requirements of the install. The only two which matter are dependency and, on Unix, dll-path.

Note

(Unix specific). On Unix, executables built with Boost.Build typically contain the list of paths to all used dynamic libraries. For installing, this is not desired, so Boost.Build relinks the executable with an empty list of paths. You can also specify additional paths for installed executables with the dll-path feature.

Testing

Boost.Build has convenient support for running unit tests. The simplest way is the unit-test rule, which follows the common syntax. For example:

unit-test helpers_test : helpers_test.cpp helpers ;

The unit-test rule behaves like the exe rule, but after the executable is created it is run. If the executable returns an error code, the build system will also return an error and will try running the executable on the next invocation until it runs successfully. This behaviour ensures that you can't miss a unit test failure.

There are rules for more elaborate testing: compile, compile-fail, run and run-fail. They are more suitable for automated testing, and are not covered here.



[6] see the definition of "free" in the section called “Feature Attributes”.


PrevUpHomeNext