Boost is a set of libraries for the C++ programming language that provide support for tasks and structures such as linear algebra, multithreading, image processing, unit testing...
The examples below demonstrate how to use biicode to set up Boost-based projects.
First let’s configure the examples project:
$ bii init boost-examples
$ cd boost-examples
We will be using that project across all the examples.
This is an example about the Boost.Lambda library, extracted from the Boost getting started header-only section.
First create a block for the example:
$ bii new your-account/boost-lambda
Create a source file:
blocks/your-account/boost-lambda/example.cpp
:
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
using namespace boost::lambda;
typedef std::istream_iterator<int> in;
std::for_each(
in(std::cin), in(), std::cout << (_1 * 3) << " " );
}
biicode sets up a Boost installation inside the biicode environment. This allows to support and switch between multiple Boost versions easily.
To enable Boost in your biicode project, just go to the block’s CMakeLists.txt
and add the following lines:
blocks/your-account/boost-lambda/CMakeLists.txt
#Include the biicode Boost setup script
include(biicode/boost/setup)
ADD_BII_TARGETS()
#Setup Boost and build (if needed) the required Boost components
#Since lambda is header-only, there are no components to build and find
bii_find_boost()
#Add Boost headers to the block include directories
target_include_directories(${BII_BLOCK_TARGET} INTERFACE ${Boost_INCLUDE_DIRS})
bii_find_boost()
is intended to wrap find_package(Boost ...)
, with almost the same input and ouput variables:
bii_find_boost([COMPONENTS component1 component2 ...] [REQUIRED])
It takes the Boost components you need, exactly as find_package(Boost)
, configures the biicode boost installation, builds that components, and then calls find_package(Boost COMPONENTS ...)
.
biicode uses the current cmake C++ compiler as Boost toolset, multiple toolsets are supported inside the same Boost version installation. Also note that, except you delete the libraries at the biicode environment, each Boost component will be built only once for each Boost version and toolset.
To configure and build your project, run bii find
to get the dependencies (The boost setup block), and then run bii configure
and bii build
as usual:
$ bii find
$ bii configure
block your-account/boost-lambda
------------------------------------------------
-- Setting up biicode Boost configuration...
-- Boost version: 1.57.0
...
$ bii build
You may notice that the example above uses Boost 1.57.0. This is the default Boost version, shipped by the biicode/boost
master track. If you want other version, say Boost 1.56.0, go to the block’s biicode.conf
file and edit the requirements entry, explicitly asking for the biicode/boost
track you want:
blocks/your-account/boost-lambda/biicode.conf
[requirements]
biicode/boost(1.56.0)
Tip
You may want to support multiple tracks for your block depending on the Boost version it uses. One way could be set different tracks for your block, matching the Boost version requested:
[requirements]
biicode/boost(1.56.0)
[parent]
your-account/boost-lambda(1.56.0): -1, 0, whatever version is available
Boost.Coroutine implements coroutines which can be useful to implement cooperative multitasking, iterators, etc, in a more natural way.
Open the Boost.Coroutine example
$ bii open examples/boost-coroutine
The example source code:
#include <boost/coroutine/all.hpp>
#include <iostream>
using namespace boost::coroutines;
void cooperative(coroutine<void>::push_type &sink)
{
std::cout << "Hello";
sink();
std::cout << "world";
}
int main()
{
coroutine<void>::pull_type source{cooperative};
std::cout << ", ";
source();
std::cout << "!\n";
}
In the code above, the string “Hello, world!” is written by writing “Hello”, going back to main()
which writes the comma, then calling the coroutine again to continue printing “world”, and finally printing ”!” on main()
.
You can visualize it as:
main() | cooperative()
--------+--------------
| "Hello"
", " |
| "world"
"!" |
This is the CMakeLists.txt
from the example:
include(biicode/boost/setup)
ADD_BII_TARGETS()
set(Boost_USE_STATIC_LIBS ON)
bii_find_boost(COMPONENTS system coroutine context thread REQUIRED)
target_include_directories(${BII_BLOCK_TARGET} INTERFACE ${Boost_INCLUDE_DIRS})
target_link_libraries(${BII_BLOCK_TARGET} INTERFACE ${Boost_LIBRARIES})
if(MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
else()
target_compile_options(${BII_BLOCK_TARGET} INTERFACE -std=c++11)
endif()
Besides Visual Studio specific configuration (See), the configuration is pretty straightforward:
Boost_USE_STATIC_LIBS
as usually when using Boost with CMake. biicode assumes static linking by default.bii_find_boost()
. Note the order matters, since it’s the order the libraries are linked together.taget_include_directories()
and Boost_INCLUDE_DIRS
variable.Boost_LIBRARIES
variable.Now just run bii configure
, wait until the Boost components are built (If those were not used previously), and then build your project with bii build
.
Configure Generator
Generators recommended for this example:
$ bii find
$ bii configure -G "Unix Makefiles"
examples/boost-corutine
---------------------------------
-- Setting up Biicode Boost...
-- Building Boost 1.57.0 components with toolset gcc-4.9.2...
-- Building system library...
-- Building coroutine library...
-- Building context library...
-- Building thread library...
-- Boost 1.57.0
Found the following Boost libraries
system
coroutine
context
thread
...
$ bii build
bii_find_boost()
sets up Boost and then calls find_package(Boost)
with the components passed to the former.
While this setup works in 90% cases, there are some situations when the Boost components you need do not correspond to Boost libraries directly.
If that’s the case, you can call bii_setup_boost()
function passing the Boost libraries to build, and then do the classic find_package(Boost COMPONENTS ...)
with the components you need.
Take Boost.Log as an example:
examples/boost-log/CMakeLists.txt
include(biicode/boost/setup)
ADD_BII_TARGETS()
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
bii_setup_boost(COMPONENTS system thread filesystem log REQUIRED)
find_package(Boost COMPONENTS system thread filesystem date_time log log_setup REQUIRED)
target_compile_options(${BII_BLOCK_TARGET} INTERFACE -DBOOST_LOG_DYN_LINK)
target_include_directories(${BII_BLOCK_TARGET} INTERFACE ${Boost_INCLUDE_DIRS})
target_link_libraries(${BII_BLOCK_TARGET} INTERFACE ${Boost_LIBRARIES})
Note how the components required by Log are not exactly the same libraries that should be built.
The Boost setup scripts have some extra variables to debug and or customize Boost a bit:
BII_BOOST_VERBOSE
: When is set to on, the setup scripts print some internal info about the current setup being run, and the different steps.BII_BOOST_LIBCXX
: When using the Clang compiler, enables Boost build using LLVM’s libc++ instead of the default GNU’s stdlibc++ standard library implementation.BII_BOOST_BUILD_J
: Specifies the number of threads used when building Boost libraries. May be useful to speed up Boost builds in setups where the libraries are always built, like continuous integration builds without cache. For example: bii configure -DBII_BOOST_BUILD_J=16
BII_BOOST_GLOBAL_USE_STATIC_LIBS
: Overrides the Boost_USE_STATIC_LIBS
values specified in each CMakeLists.txt
and sets a value globally. Useful when you depend on many Boost-related blocks and you may experience issues related to different linkages against Boost in that blocks. Use this variable carefully.The setup scripts are maintained as an open source project on GitHub, you may want to ask about new features, report bugs, etc.