oneTBB: интеграция и сборка через CMake

oneAPI Threading Building Blocks (oneTBB) — популярная библиотека для параллельного программирования на C++ с открытым исходным кодом, опубликована на GitHub. Пару лет назад команда разработки решилась на глобальный рефакторинг библиотеки (проект TBB revamp), в который удалось вписать долгожданную смену системы сборки с GNU Makefiles на CMake. Свежая версия вышла в релиз в рамках инициативы oneAPI, обновив имя на oneTBB. В этой статье я расскажу про то, как подключить oneTBB в CMake-проект и как собрать, протестировать и установить oneTBB.

Как подключить oneTBB в свой CMake-проект

Эта часть может быть полезна тем, кто хочет использовать библиотеку oneTBB в своём проекте.

Существует два основных способа подключения стороннего проекта: как готовый пакет и как исходный код.

Способ 1. Подключение готового пакета oneTBB

Для подключения пакета нужна функция find_package(TBB <...>). Такой способ работает для тех пакетов oneTBB, в которых есть соответствующая поддержка — TBBConfig-файлы. Официальные oneAPI пакеты распространяются с такой поддержкой из коробки. Архивы, прикреплённые к релизам oneTBB на GitHub, тоже поддерживают такой способ, но нужно дать CMake’у знать, куда распакован пакет, через переменную CMAKE_PREFIX_PATH. Некоторые сторонние дистрибутивы oneTBB также поддерживают этот способ. На самом деле, поддержка TBBConfig-файлов появилась задолго до релиза oneTBB, это произошло в одном из обновлений TBB 2017. Реализация в oneTBB во многом совместима с реализацией из предыдущих версий.

После успешного вызова find_package(TBB <...>) в проекте станут доступны импортированные таргеты TBB::tbb, TBB::tbbmalloc и т.д. в зависимости от запрошенных и доступных компонентов. Эти таргеты можно подключить к своему таргету — target_link_libraries(my_app PRIVATE TBB::tbb). Несмотря на «link» в названии функции, она добавит зависимость не только на стадию линковки, но и на стадию компиляции (путь до заголовочных файлов oneTBB подставится в строку компиляции).

Код
# Создаём приложение
add_executable(my_app)
target_sources(my_app PRIVATE my_app.cpp) # Ищем готовый пакет oneTBB 2021.5.0 (или новее)
find_package(TBB 2021.5.0 REQUIRED) # Подключаем импортированный таргет TBB::tbb к приложению
target_link_libraries(my_app PRIVATE TBB::tbb)

Детальнее посмотреть и попробовать этот способ можно на примере, в котором:

  • my_app.cpp — исходник приложения, вызывающего TBB_runtime_version() и печатающего результат в консоль;

  • CMakeLists.txt — CMake-конфигурация для сборки приложения, где и показан способ подключения oneTBB;

  • run.sh — скрипт для запуска примера на линуксе;

  • README.md — небольшое описание примера.

В этом примере используется готовый пакет со страницы oneTBB/releases, который ставится в текущую папку. Такая CMake-конфигурация будет работать и в случае установки oneTBB из многих других источников.

Во время сборки можно заметить, как подключается библиотека:

  • на этапе компиляции подключаются заголовочные файлы: -isystem <onetbb-root>/include

  • на этапе линковки проставляется rpath и подключается библиотека: -Wl,-rpath,<onetbb-root>/lib/intel64/gcc4.8 <onetbb-root>/lib/intel64/gcc4.8/libtbb.so.12

Так как путь до библиотеки уже есть в rpath, для запуска не нужно выставлять какие-то дополнительные переменные окружения. С помощью ldd можно проверить, что oneTBB «виден»:

> ldd ./build/my_app | grep tbb
        libtbb.so.12 => <onetbb-root>/lib/intel64/gcc4.8/libtbb.so.12 (0x00007f867622c000)

Способ 2. Подключение oneTBB в виде исходного кода

Если подходящего пакета нет или требуется сборка с особыми параметрами, то можно использовать исходный код oneTBB, собирая его вместе с проектом.

До вызова функции, подключающей oneTBB, можно дополнительно настроить конфигурацию с помощью переменных, которые описаны в начале oneTBB/cmake/README.md (TBB_STRICT, TBB_TEST и т.д.), общие переменные CMAKE_BUILD_TYPE, CMAKE_CXX_STANDARD и другие также будут учитываться при построении oneTBB.

В самом простом варианте можно скачать исходники библиотеки в папку с проектом и добавить в CMakeLists.txt команду add_subdirectory(<onetbb-sources-dir>). Дальше можно использовать таргеты из oneTBB проекта и подключать их к своим таргетам, как в способе 1 — target_link_libraries(my_app PRIVATE TBB::tbb).

Код
# Создаём приложение
add_executable(my_app)
target_sources(my_app PRIVATE my_app.cpp) # Настраиваем конфигурацию oneTBB - явно отключаем тесты
option(TBB_TEST OFF) # Подключаем в проект подпапку с исходниками oneTBB,
# которая должна быть предварительно скачана в проект
add_subdirectory(oneTBB) # Подключаем таргет TBB::tbb к приложению
target_link_libraries(my_app PRIVATE TBB::tbb)

Вместо add_subdirectory можно использовать функции FetchContent_Declare и FetchContent_MakeAvailable из модуля FetchContent, что позволит автоматически скачивать исходники oneTBB, например с GitHub.

Код
# Создаём таргет приложения
add_executable(my_app)
target_sources(my_app PRIVATE my_app.cpp) # Загружаем исходники oneTBB 2021.5.0 с GitHub на этапе конфигурации
include(FetchContent)
FetchContent_Declare( onetbb GIT_REPOSITORY https://github.com/oneapi-src/oneTBB.git GIT_TAG v2021.5.0
) # Настраиваем конфигурацию oneTBB - явно отключаем тесты
option(TBB_TEST OFF) # Делаем исходники oneTBB доступными в текущем проекте (аналогично add_subdirectory)
FetchContent_MakeAvailable(onetbb) # Подключаем таргет TBB::tbb к приложению
target_link_libraries(my_app PRIVATE TBB::tbb)

Детальнее посмотреть и попробовать этот способ можно на примере, в котором:

  • my_app.cpp — исходник приложения, вызывающего TBB_runtime_version() и печатающего результат в консоль;

  • CMakeLists.txt — CMake-конфигурация для сборки приложения, где и показан способ подключения oneTBB с помощью модуля FetchContent;

  • run.sh — скрипт для запуска примера на линуксе;

  • README.md — небольшое описание примера.

При построении явно используется таргет my_app, который через зависимость вызывает построение таргета TBB::tbb. Если не использовать никакого таргета или использовать таргет all, то построятся все таргеты из проекта oneTBB, попавшие в all, а не только те, на которые есть зависимость.

Как сконфигурировать, построить и протестировать oneTBB

Эта часть может быть полезна тем, кто хочет самостоятельно собирать oneTBB, делать какие-то доработки и предлагать изменения в библиотеку.

Подробное и актуальное описание системы сборки можете найти в oneTBB/cmake/README.md. Ниже кратко опишу основные шаги.

Конфигурация

Конфигурируется проект типично — командой cmake. Настроить конфигурацию можно как общими переменными (CMAKE_BUILD_TYPE, CMAKE_CXX_STANDARD и т.д.), так и проектными (TBB_STRICT, TBB_TEST и т.д.).

Построение

Строится проект также типично: например, командой cmake --build. Проект включает в себя несколько компонентов, для каждого из которых есть таргет, если компонент поддерживается на системе и не отключен при конфигурации: tbb, tbbmalloc, tbbmalloc_proxy, разные варианты tbbbind. Каждый из этих таргетов строится в динамическую библиотеку. Статическую версию тоже можно построить (BUILD_SHARED_LIBS), но разработчики oneTBB не рекомендуют и официально не поддерживают такой вариант.

В проект входят Python-bindings (таргет python_build), которые включаются опцией TBB4PY_BUILD и собираются через Setuptools под капотом. Для сборки нужен Python 3.5+ и SWIG.

Если тесты не отключены через TBB_TEST=OFF, то для каждого из них создаётся таргет, который можно построить отдельно.

Тестирование

При включенной опции TBB_TEST в проект включаются тесты. Набор тестов зависит от включенных компонентов и от платформы. Тесты будут включать дополнительные сценарии, если в системе установлен Intel® Software Development Emulator. Построенные тесты можно запустить с помощью утилиты ctest.

Установка

Подробная инструкция установки из исходников с примерами описана в oneTBB/INSTALL.md.

Для установки можно использовать таргет install, либо напрямую вызывать cmake_install.cmake скрипт, с помощью которого можно установить конкретный компонент:runtime, devel или tbb4py.

Настроить путь установки можно на этапе конфигурации проекта через переменную CMAKE_INSTALL_PREFIX. По умолчанию установится в /usr/local на Unix и в C:\Program Files\TBB на Windows.

Кроме того, в проекте реализована простая zip конфигурация для упаковщика CPack. После конфигурации и сборки проекта можно сделать oneTBB пакет в виде zip-архива. В распакованном виде такой пакет можно подключать к проектам, как описано выше в способе 1.


Более подробную и актуальную информацию о системе сборки (и не только) можно найти в репозитории oneTBB на GitHub. Проект активный, поэтому баг-репорты, фича-реквесты или просто вопросы приветствуются через Issues, а свой вклад можно внести через Pull Request.

Читайте так же:

  • Спуфинг sAMAccountName: от LowPriv до домен админа за шесть командСпуфинг sAMAccountName: от LowPriv до домен админа за шесть команд Сап, Хабр!Значится, сидим мы с коллегой (привет, @Acrono!) на площадке у Заказчика, воткнутые в скоммутированную сетевую розетку, да пентестим свои внутряки. Повсюду эти ваши 802.1x, AppLocker-ы, PowerShell CLM-ы, LAPS-ы, аверы лютуют, блоча попытки получить заветный хендл к lsass.exe, […]
  • Методы оптимизации сайта, увеличение скорости загрузки сайта. Исследование спроса для маркетплейсовМетоды оптимизации сайта, увеличение скорости загрузки сайта. Исследование спроса для маркетплейсов Описание Москвин Александр ЛитРес Методы оптимизации сайта, увеличение скорости загрузки сайта —  Зачем нужно оптимизировать скорость загрузки сайта? — Способы оптимизации сайта со стороны front-end — Способы оптимизации со стороны сервера — Кэширование как способ оптимизации сайта […]
  • Первые детали о Samsung Galaxy F22: смартфон будет построен на базе Galaxy A22Первые детали о Samsung Galaxy F22: смартфон будет построен на базе Galaxy A22 Как сообщает SamMobile. Линейка Samsung Galaxy F собирается получить новую модель. Которая будет относиться к бюджетной категории. Предположительно. Следующая модель будет выпущена под названием Samsung Galaxy F22. По словам инсайдера из Twitter с ником _the_tech_guy, южнокорейский […]
  • Как прошла ПЛИСовая конференция в Питере?Как прошла ПЛИСовая конференция в Питере? Прошло всё отлично, 35 человек собралось, 7 докладов выслушано, 12 человек осталось на афтерпати.Следующее мероприятие пройдет в Москве, Минске, Томске и Санкт-Петербурге в апреле-мае, подробности тут.Все материалы собраны в отдельные плейлисты - встреча в Москве // […]