# Build system description

The project uses CMake build configuration.

The following controls are available during the configure stage:
```
TBB_TEST:BOOL - Enable testing (ON by default)
TBB_STRICT:BOOL - Treat compiler warnings as errors (ON by default)
TBB_SANITIZE:STRING - Sanitizer parameter, passed to compiler/linker
TBB_SIGNTOOL:FILEPATH - Tool for digital signing, used in post install step for libraries if provided.
TBB_SIGNTOOL_ARGS:STRING - Additional arguments for TBB_SIGNTOOL, used if TBB_SIGNTOOL is set.
TBB_BUILD:BOOL - Enable Intel(R) oneAPI Threading Building Blocks (oneTBB) build (ON by default)
TBBMALLOC_BUILD:BOOL - Enable Intel(R) oneAPI Threading Building Blocks (oneTBB) memory allocator build (ON by default)
TBB4PY_BUILD:BOOL - Enable Intel(R) oneAPI Threading Building Blocks (oneTBB) Python module build (OFF by default)
TBB_CPF:BOOL - Enable preview features of the library (OFF by default)
TBB_INSTALL_VARS:BOOL - Enable auto-generated vars installation(packages generated by `cpack` and `make install` will also include the vars script)(OFF by default)
TBB_VALGRIND_MEMCHECK:BOOL - Enable scan for memory leaks using Valgrind (OFF by default)
TBB_DISABLE_HWLOC_AUTOMATIC_SEARCH - Disable HWLOC automatic search by pkg-config tool (OFF by default)
```

## Configure, build and test

### Prerequisites

*  CMake >= 3.1

### Preparation

In order to perform out-of-source build you have to create a build directory and go there:

```bash
mkdir /tmp/my-build
cd /tmp/my-build
```

### Configure

```bash
cmake <options> <repo_root>
```

Some useful options:
- `-G <generator>` - specify particular project generator, see `cmake --help` for details.
- `-DCMAKE_BUILD_TYPE=Debug` - specify for Debug build, it isn't applicable for multi-config generators, e.g. for Visual Studio generator).

#### TBBBind library configuration

The TBBbind library has three versions: `tbbbind`, `tbbbind_2_0` and `tbbbind_2_5`. Each of these versions is linked with corresponding HWLOC library version: `tbbbind` links with HWLOC 1.11.x , `tbbbind_2_0` links with HWLOC 2.1-2.4, `tbbbind_2_5` links with HWLOC 2.5 and later.

The search for a suitable version of the HWLOC library is enabled by default, but if you want to use a specific version of the library, you can specify the path to it manually using the following CMake variables:

 - `CMAKE_HWLOC_<HWLOC_VER>_LIBRARY_PATH` - path to the corresponding HWLOC version shared library on Linux or path to `.lib` file on Windows.
 - `CMAKE_HWLOC_<HWLOC_VER>_INCLUDE_PATH` - path to the corresponding HWLOC version includes directory.

Automatic HWLOC searching requires CMake >= 3.6.

Windows requires one additional variable for correct TBBBind library building:
 - `CMAKE_HWLOC_<HWLOC_VER>_DLL_PATH` - path to the corresponding HWLOC version `.dll` file.

`HWLOC_VER` substring used above can be replaced with one of the three values: `1_11` for the `tbbbind` library configuration, `2` for the `tbbbind_2_0`, and `2_5` for the `tbbbind_2_5` library configuration.

If you specify variables for several TBBBind versions, then building process for all of these versions will be performed during single build session.

Specify the `TBB_DISABLE_HWLOC_AUTOMATIC_SEARCH` to disable HWLOC libraries automatic search.

### Build

```bash
cmake --build . <options>
```

Some useful options:
- `--target <target>` - specific target, "all" is default.
- `--config <Release|Debug>` - build configuration, applicable only for multi-config generators, e.g. Visual Studio generator.

Binaries are placed to `./<compiler-id>_<compiler-ver>_cxx<stdver>_<build-type>` (for example, `./gnu_4.8_cxx11_release`)

#### Build for 32-bit

* Intel Compiler: just source Intel(R) C++ Compiler with `ia32` and build as usual.
* MSVC: use switch for [generator](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) (e.g. `-A Win32` for [VS2019](https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2016%202019.html)) during the configuration stage and then build as usual.
* GCC/Clang: specify `-m32` during the configuration: `CXXFLAGS=-m32 cmake ..` or `cmake -DCMAKE_CXX_FLAGS=-m32 ..`
* Any other compiler which builds for 64-bit by default: specify 32-bit compiler key during the configuration as above.

#### Windows specific builds (CMake 3.15 or newer is required)

* Dynamic linkage with CRT: default behavior, can be explicitly specified by setting `CMAKE_MSVC_RUNTIME_LIBRARY` to `MultiThreadedDLL` or `MultiThreadedDebugDLL`.
```bash
cmake ..  # dynamic linkage is used by default
```
```bash
cmake -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL ..
```
```bash
cmake -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebugDLL -DCMAKE_BUILD_TYPE=Debug ..
```
* Static linkage with CRT: set `CMAKE_MSVC_RUNTIME_LIBRARY` to `MultiThreaded` or `MultiThreadedDebug`.
```bash
cmake -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded ..
```
```bash
cmake -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug -DCMAKE_BUILD_TYPE=Debug ..
```
* Windows 10 Universal Windows application build: set `CMAKE_SYSTEM_NAME` to `WindowsStore` and `CMAKE_SYSTEM_VERSION` to `10.0`.

_Note: set `TBB_NO_APPCONTAINER` to `ON` in order to apply `/APPCONTAINER:NO` option during the compilation (used for testing)._
```bash
cmake -DCMAKE_SYSTEM_NAME:STRING=WindowsStore -DCMAKE_SYSTEM_VERSION:STRING=10.0 ..
```
* Universal Windows Driver build: set `TBB_WINDOWS_DRIVER` to `ON` and use static linkage with CRT (see above).

```bash
cmake -DTBB_WINDOWS_DRIVER=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded ..
```

### Test

#### Build test
Using default ('all') target:
```
cmake --build .
```

or using specific test target:
```
cmake --build . --target <test> # e.g. test_version
```

#### Run test

Using CTest:
```bash
ctest
```

or using 'test' target:
```bash
cmake --build . --target test # currently doesn't work on Windows
```

## Sanitizers - сonfigure, build and run

```bash
mkdir build
cd build
cmake -DTBB_SANITIZE=thread ..  # or -DTBB_SANITIZE=memory or any other sanitizer
make -j
ctest -V
```

## Valgrind memcheck - configure, build and run

### Prerequisites
* Valgrind tool executable
### Example
```bash
mkdir build
cd build
cmake -DTBB_VALGRIND_MEMCHECK=ON ..
make -j memcheck-<test name> # or memcheck-all to scan all tests 
```

## Test specification (Doxygen)

```bash
mkdir build
cd build
cmake -DTBB_TEST_SPEC=ON ..
make test_spec
```

## Intallation and packaging

**NOTE: be careful about installation: avoid commands like `make install` unless you fully understand the consequences.**

The following install components are supported:
- `runtime` - oneTBB runtime package (core shared libraries and `.dll` files on Windows).
- `devel` - oneTBB development package (header files, CMake integration files, library symbolic links and `.lib` files on Windows).
- `tbb4py` - [oneTBB Module for Python](#onetbb-python-module-support).

How to install specific components after configuration and build:

```bash
cmake -DCOMPONENT=<component> [-DBUILD_TYPE=<build-type>] -P cmake_install.cmake
```

Simple packaging using CPack is supported.
The following commands allow to create a simple portable package which includes header files, libraries and integration files for CMake:

```bash
cmake <options> ..
cpack
```

## TBBConfig - integration of binary packages

It is a configuration module that is used for integration of prebuilt oneTBB. It consists of two files (TBBConfig.cmake and TBBConfigVersion.cmake) and can be used via [find_package](https://cmake.org/cmake/help/latest/command/find_package.html) function.

How to use this module in your CMake project:
 1. Let CMake know where to search for TBBConfig, e.g. specify location of TBBConfig.cmake in `TBB_DIR` (for more details about search paths see [find_package](https://cmake.org/cmake/help/latest/command/find_package.html)).
 2. Use [find_package](https://cmake.org/cmake/help/latest/command/find_package.html) to find oneTBB.
 3. Use provided variables and/or imported targets (described below) to work with the found oneTBB.

Example:

```cmake
add_executable(foo foo.cpp)
find_package(TBB)
target_link_libraries(foo TBB::tbb)
```

oneTBB components can be passed to [find_package](https://cmake.org/cmake/help/latest/command/find_package.html) after keyword ``COMPONENTS`` or ``REQUIRED``.
Use basic names of components (`tbb`, `tbbmalloc`, etc.).

If components are not specified then the default set is used: `tbb`, `tbbmalloc` and ``tbbmalloc_proxy``.

If `tbbmalloc_proxy` is requested, `tbbmalloc` component will also be added and set as dependency for `tbbmalloc_proxy`.

TBBConfig creates [imported targets](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#imported-targets>) as
shared libraries using the following format: `TBB::<component>` (for example, `TBB::tbb`, `TBB::tbbmalloc`).

Set `TBB_FIND_RELEASE_ONLY` to `TRUE` before calling `find_package` in order to search only for release oneTBB version. This variable helps to avoid simultaneous linkage of release and debug oneTBB versions when CMake configuration is `Debug` but a third-party component depends on release oneTBB version.

Variables set during TBB configuration:

Variable | Description
--- | ---
`TBB_FOUND`             | oneTBB is found
`TBB_<component>_FOUND` | Specific oneTBB component is found
`TBB_VERSION`           | oneTBB version (format: `<major>.<minor>.<patch>.<tweak>`)
`TBB_IMPORTED_TARGETS`  | All created oneTBB imported targets (not supported for builds from source code)

Starting from [oneTBB 2021.1](https://github.com/oneapi-src/oneTBB/releases/tag/v2021.1) GitHub release TBBConfig files in the binary packages are located under `<tbb-root>/lib/cmake/TBB`.
For example, `TBB_DIR` should be set to `<tbb-root>/lib/cmake/TBB`.

TBBConfig files are automatically created during the build from source code and can be installed together with the library.
Also oneTBB provides a helper function that creates TBBConfig files from predefined templates: see `tbb_generate_config` in `cmake/config_generation.cmake`.

## oneTBB Python Module support
`TBB4PY_BUILD` Cmake option provides ability to build Python module for oneTBB.

### Targets:
 - `irml` - build IPC RML server
 - `python_build` - build oneTBB module for Python

`python_build` target requirements:
 - Python version 3.5 or newer
 - SWIG version 3.0.6 or newer

## CMake files

### Compile/link options

Compile and link options may be specific for certain compilers. This part is handled in `cmake/compilers/*` files.

Options in TBB CMake are handled via variables in two ways for convenience:

*  by options group
*  by specific option

#### Options group

Naming convention is the following: `TBB_<SCOPE>_<STAGE>_<CATEGORY>`, where

*  `<SCOPE>` could be
    *  `LIB` - options applied during libraries build.
    *  `TEST` - options applied during test build.
    *  `BENCH` - options applied during benchmarks build.
    *  `COMMON` - options applied during all (libraries, test, benchmarks) builds.
*  `<STAGE>` could be
    *  `COMPILE` - options applied during the compilation.
    *  `LINK` - options applied during the linkage.
*  `<CATEGORY>` could be
    *  `FLAGS` - list of flags
    *  `LIBS` - list of libraries

*Examples*

Variable | Description
--- | ---
`TBB_COMMON_COMPILE_FLAGS` | Applied to libraries, tests and benchmarks as compile options
`TBB_LIB_LINK_FLAGS`       | Applied to libraries as link options
`TBB_LIB_LINK_LIBS `       | Applied to libraries as link libraries
`TBB_TEST_COMPILE_FLAGS`   | Applied to tests as compile options

Please specify the `LINK` options prefixed with dash(-) for MSVC(Visual Studio) compiler with CMake < 3.13 to avoid issues caused by `target_link_libraries` CMake command usage.

#### Specific options

If the option used only in part of the places (library, tests, benchmarks) as well as adding this option to the group of other options is not possible,
then the option must be named using common sense.

Warnings supperssions should be added into `TBB_WARNING_SUPPRESS` variable which is applied during the compilation of libraries, tests and benchmarks.
Additional warnings should be added into `TBB_WARNING_TEST_FLAGS` variable which is applied during the compilation of tests.
