1# Copyright (c) 2020-2024 Intel Corporation 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15cmake_minimum_required(VERSION 3.5) 16 17# Enable CMake policies 18 19if (POLICY CMP0068) 20 # RPATH settings do not affect install_name on macOS since CMake 3.9 21 cmake_policy(SET CMP0068 NEW) 22endif() 23 24if (POLICY CMP0091) 25 # The NEW behavior for this policy is to not place MSVC runtime library flags in the default 26 # CMAKE_<LANG>_FLAGS_<CONFIG> cache entries and use CMAKE_MSVC_RUNTIME_LIBRARY abstraction instead. 27 cmake_policy(SET CMP0091 NEW) 28elseif (DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) 29 message(FATAL_ERROR "CMAKE_MSVC_RUNTIME_LIBRARY was defined while policy CMP0091 is not available. Use CMake 3.15 or newer.") 30endif() 31 32if (TBB_WINDOWS_DRIVER AND (NOT ("${CMAKE_MSVC_RUNTIME_LIBRARY}" STREQUAL MultiThreaded OR "${CMAKE_MSVC_RUNTIME_LIBRARY}" STREQUAL MultiThreadedDebug))) 33 message(FATAL_ERROR "Enabled TBB_WINDOWS_DRIVER requires CMAKE_MSVC_RUNTIME_LIBRARY to be set to MultiThreaded or MultiThreadedDebug.") 34endif() 35 36# Enable support of minimum supported macOS version flag 37if (APPLE) 38 if (NOT CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG) 39 set(CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG "-mmacosx-version-min=" CACHE STRING "Minimum macOS version flag") 40 endif() 41 if (NOT CMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG) 42 set(CMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG "-mmacosx-version-min=" CACHE STRING "Minimum macOS version flag") 43 endif() 44endif() 45 46file(READ include/oneapi/tbb/version.h _tbb_version_info) 47string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1" _tbb_ver_major "${_tbb_version_info}") 48string(REGEX REPLACE ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1" _tbb_ver_minor "${_tbb_version_info}") 49string(REGEX REPLACE ".*#define TBB_VERSION_PATCH ([0-9]+).*" "\\1" _tbb_ver_patch "${_tbb_version_info}") 50string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_tbb_version_info}") 51string(REGEX REPLACE ".*#define __TBB_BINARY_VERSION ([0-9]+).*" "\\1" TBB_BINARY_VERSION "${_tbb_version_info}") 52set(TBB_BINARY_MINOR_VERSION ${_tbb_ver_minor}) 53set(TBBMALLOC_BINARY_VERSION 2) 54set(TBBBIND_BINARY_VERSION 3) 55 56project(TBB VERSION ${_tbb_ver_major}.${_tbb_ver_minor}.${_tbb_ver_patch} LANGUAGES CXX) 57unset(_tbb_ver_major) 58unset(_tbb_ver_minor) 59 60include(CheckCXXCompilerFlag) 61include(GNUInstallDirs) 62include(CMakeDependentOption) 63 64# --------------------------------------------------------------------------------------------------------- 65# Handle C++ standard version. 66if (NOT MSVC) # no need to cover MSVC as it uses C++14 by default. 67 if (NOT CMAKE_CXX_STANDARD) 68 set(CMAKE_CXX_STANDARD 11) 69 endif() 70 71 if (CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION) # if standard option was detected by CMake 72 set(CMAKE_CXX_STANDARD_REQUIRED ON) 73 else() # if standard option wasn't detected by CMake (e.g. for Intel Compiler with CMake 3.1) 74 # TBB_CXX_STD_FLAG should be added to targets via target_compile_options 75 set(TBB_CXX_STD_FLAG -std=c++${CMAKE_CXX_STANDARD}) 76 77 check_cxx_compiler_flag(${TBB_CXX_STD_FLAG} c++${CMAKE_CXX_STANDARD}) 78 if (NOT c++${CMAKE_CXX_STANDARD}) 79 message(FATAL_ERROR "C++${CMAKE_CXX_STANDARD} (${TBB_CXX_STD_FLAG}) support is required") 80 endif() 81 unset(c++${CMAKE_CXX_STANDARD}) 82 endif() 83endif() 84 85set(CMAKE_CXX_EXTENSIONS OFF) # use -std=c++... instead of -std=gnu++... 86# --------------------------------------------------------------------------------------------------------- 87 88# Detect architecture (bitness). 89if (CMAKE_SIZEOF_VOID_P EQUAL 4) 90 set(TBB_ARCH 32) 91else() 92 set(TBB_ARCH 64) 93endif() 94 95option(TBB_TEST "Enable testing" ON) 96option(TBB_EXAMPLES "Enable examples" OFF) 97option(TBB_STRICT "Treat compiler warnings as errors" ON) 98option(TBB_WINDOWS_DRIVER "Build as Universal Windows Driver (UWD)" OFF) 99option(TBB_NO_APPCONTAINER "Apply /APPCONTAINER:NO (for testing binaries for Windows Store)" OFF) 100option(TBB4PY_BUILD "Enable tbb4py build" OFF) 101option(TBB_BUILD "Enable tbb build" ON) 102option(TBBMALLOC_BUILD "Enable tbbmalloc build" ON) 103cmake_dependent_option(TBBMALLOC_PROXY_BUILD "Enable tbbmalloc_proxy build" ON "TBBMALLOC_BUILD" OFF) 104option(TBB_CPF "Enable preview features of the library" OFF) 105option(TBB_FIND_PACKAGE "Enable search for external oneTBB using find_package instead of build from sources" OFF) 106option(TBB_DISABLE_HWLOC_AUTOMATIC_SEARCH "Disable HWLOC automatic search by pkg-config tool" ${CMAKE_CROSSCOMPILING}) 107option(TBB_ENABLE_IPO "Enable Interprocedural Optimization (IPO) during the compilation" ON) 108option(TBB_FUZZ_TESTING "Enable fuzz testing" OFF) 109option(TBB_INSTALL "Enable installation" ON) 110 111if (NOT DEFINED BUILD_SHARED_LIBS) 112 set(BUILD_SHARED_LIBS ON) 113endif() 114 115if (NOT BUILD_SHARED_LIBS) 116 if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) 117 set(CMAKE_POSITION_INDEPENDENT_CODE ON) 118 endif() 119 message(WARNING "You are building oneTBB as a static library. This is highly discouraged and such configuration is not supported. Consider building a dynamic library to avoid unforeseen issues.") 120endif() 121 122if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 123 set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type" FORCE) 124 message(STATUS "CMAKE_BUILD_TYPE is not specified. Using default: ${CMAKE_BUILD_TYPE}") 125 # Possible values of build type for cmake-gui 126 set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") 127endif() 128 129if (CMAKE_BUILD_TYPE) 130 string(TOLOWER ${CMAKE_BUILD_TYPE} _tbb_build_type) 131 if (_tbb_build_type STREQUAL "debug") 132 set(TBB_ENABLE_IPO OFF) 133 endif() 134 unset(_tbb_build_type) 135endif() 136 137# ------------------------------------------------------------------- 138# Files and folders naming 139set(CMAKE_DEBUG_POSTFIX _debug) 140 141if (NOT DEFINED TBB_OUTPUT_DIR_BASE) 142 if (MSVC) 143 if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY OR CMAKE_MSVC_RUNTIME_LIBRARY MATCHES DLL) 144 set(_tbb_msvc_runtime _md) 145 else() 146 set(_tbb_msvc_runtime _mt) 147 endif() 148 149 if (WINDOWS_STORE) 150 if (TBB_NO_APPCONTAINER) 151 set(_tbb_win_store _wsnoappcont) 152 else() 153 set(_tbb_win_store _ws) 154 endif() 155 elseif(TBB_WINDOWS_DRIVER) 156 set(_tbb_win_store _wd) 157 endif() 158 endif() 159 160 string(REGEX MATCH "^([0-9]+\.[0-9]+|[0-9]+)" _tbb_compiler_version_short ${CMAKE_CXX_COMPILER_VERSION}) 161 string(TOLOWER ${CMAKE_CXX_COMPILER_ID}_${_tbb_compiler_version_short}_cxx${CMAKE_CXX_STANDARD}_${TBB_ARCH}${_tbb_msvc_runtime}${_tbb_win_store} TBB_OUTPUT_DIR_BASE) 162 unset(_tbb_msvc_runtime) 163 unset(_tbb_win_store) 164 unset(_tbb_compiler_version_short) 165endif() 166 167foreach(output_type LIBRARY ARCHIVE PDB RUNTIME) 168 if (CMAKE_BUILD_TYPE) 169 string(TOLOWER ${CMAKE_BUILD_TYPE} _tbb_build_type_lower) 170 set(CMAKE_${output_type}_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${TBB_OUTPUT_DIR_BASE}_${_tbb_build_type_lower}) 171 unset(_tbb_build_type_lower) 172 endif() 173 174 if (CMAKE_CONFIGURATION_TYPES) 175 foreach(suffix ${CMAKE_CONFIGURATION_TYPES}) 176 string(TOUPPER ${suffix} _tbb_suffix_upper) 177 string(TOLOWER ${suffix} _tbb_suffix_lower) 178 set(CMAKE_${output_type}_OUTPUT_DIRECTORY_${_tbb_suffix_upper} ${CMAKE_BINARY_DIR}/${TBB_OUTPUT_DIR_BASE}_${_tbb_suffix_lower}) 179 endforeach() 180 unset(_tbb_suffix_lower) 181 unset(_tbb_suffix_upper) 182 endif() 183endforeach() 184 185if (CMAKE_CONFIGURATION_TYPES) 186 # We can't use generator expressions in a cmake variable name. 187 set(TBB_TEST_WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${TBB_OUTPUT_DIR_BASE}_$<LOWER_CASE:$<CONFIG>>) 188else() 189 set(TBB_TEST_WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) 190endif() 191 192# ------------------------------------------------------------------- 193 194# ------------------------------------------------------------------- 195# Common dependencies 196#force -pthread during compilation for Emscripten 197if (EMSCRIPTEN AND NOT EMSCRIPTEN_WITHOUT_PTHREAD) 198 set(THREADS_HAVE_PTHREAD_ARG TRUE) 199endif() 200 201set(THREADS_PREFER_PTHREAD_FLAG TRUE) 202find_package(Threads REQUIRED) 203# ------------------------------------------------------------------- 204 205file(GLOB FILES_WITH_EXTRA_TARGETS ${CMAKE_CURRENT_SOURCE_DIR}/cmake/*.cmake) 206foreach(FILE_WITH_EXTRA_TARGETS ${FILES_WITH_EXTRA_TARGETS}) 207 include(${FILE_WITH_EXTRA_TARGETS}) 208endforeach() 209 210# - Enabling LTO on Android causes the NDK bug. 211# NDK throws the warning: "argument unused during compilation: '-Wa,--noexecstack'" 212# - For some reason GCC does not instrument code with Thread Sanitizer when lto is enabled and C linker is used. 213if (TBB_ENABLE_IPO AND BUILD_SHARED_LIBS AND NOT ANDROID_PLATFORM AND NOT TBB_SANITIZE MATCHES "thread") 214 if (NOT CMAKE_VERSION VERSION_LESS 3.9) 215 cmake_policy(SET CMP0069 NEW) 216 include(CheckIPOSupported) 217 check_ipo_supported(RESULT TBB_IPO_PROPERTY) 218 else() 219 set(TBB_IPO_FLAGS TRUE) 220 endif() 221 if (TBB_IPO_PROPERTY OR TBB_IPO_FLAGS) 222 message(STATUS "IPO enabled") 223 endif() 224endif() 225 226set(TBB_COMPILER_SETTINGS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compilers/${CMAKE_CXX_COMPILER_ID}.cmake) 227if (EXISTS ${TBB_COMPILER_SETTINGS_FILE}) 228 include(${TBB_COMPILER_SETTINGS_FILE}) 229else() 230 message(WARNING "TBB compiler settings not found ${TBB_COMPILER_SETTINGS_FILE}") 231endif() 232 233if (TBB_FIND_PACKAGE OR TBB_DIR) 234 # Allow specifying external TBB to test with. 235 # Do not add main targets and installation instructions in that case. 236 message(STATUS "Using external TBB for testing") 237 find_package(TBB REQUIRED) 238else() 239 if (TBB_BUILD) 240 add_subdirectory(src/tbb) 241 endif() 242 if (TBBMALLOC_BUILD) 243 add_subdirectory(src/tbbmalloc) 244 if(TBBMALLOC_PROXY_BUILD AND NOT "${MSVC_CXX_ARCHITECTURE_ID}" MATCHES "ARM64") 245 add_subdirectory(src/tbbmalloc_proxy) 246 endif() 247 endif() 248 if (NOT BUILD_SHARED_LIBS) 249 message(STATUS "TBBBind build targets are disabled due to unsupported environment") 250 else() 251 add_subdirectory(src/tbbbind) 252 endif() 253 if (TBB_INSTALL) 254 # ------------------------------------------------------------------- 255 # Installation instructions 256 include(CMakePackageConfigHelpers) 257 258 install(DIRECTORY include/ 259 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 260 COMPONENT devel) 261 262 install(EXPORT ${PROJECT_NAME}Targets 263 NAMESPACE TBB:: 264 DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 265 COMPONENT devel) 266 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake 267 "include(\${CMAKE_CURRENT_LIST_DIR}/${PROJECT_NAME}Targets.cmake)\n") 268 if (NOT BUILD_SHARED_LIBS) 269 file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake 270 "include(CMakeFindDependencyMacro)\nfind_dependency(Threads)\n") 271 endif() 272 273 write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 274 COMPATIBILITY AnyNewerVersion) 275 276 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 277 "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 278 DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 279 COMPONENT devel) 280 281 install(FILES "README.md" 282 DESTINATION ${CMAKE_INSTALL_DOCDIR} 283 COMPONENT devel) 284 # ------------------------------------------------------------------- 285 endif() 286endif() 287 288if (TBB_TEST) 289 enable_testing() 290 add_subdirectory(test) 291endif() 292 293if (TBB_EXAMPLES) 294 add_subdirectory(examples) 295endif() 296 297if (TBB_BENCH) 298 if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/benchmark) 299 message(FATAL_ERROR "Benchmarks are not supported yet") 300 endif() 301 302 enable_testing() 303 add_subdirectory(benchmark) 304endif() 305 306if (ANDROID_PLATFORM) 307 if ("${ANDROID_STL}" STREQUAL "c++_shared") 308 if (${ANDROID_NDK_MAJOR} GREATER_EQUAL "25") 309 if(ANDROID_ABI STREQUAL "arm64-v8a") 310 set(ANDROID_TOOLCHAIN_NAME "aarch64-linux-android") 311 elseif(ANDROID_ABI STREQUAL "x86_64") 312 set(ANDROID_TOOLCHAIN_NAME "x86_64-linux-android") 313 elseif(ANDROID_ABI STREQUAL "armeabi-v7a") 314 set(ANDROID_TOOLCHAIN_NAME "arm-linux-androideabi") 315 elseif(ANDROID_ABI STREQUAL "x86") 316 set(ANDROID_TOOLCHAIN_NAME "i686-linux-android") 317 endif() 318 319 configure_file( 320 "${ANDROID_TOOLCHAIN_ROOT}/sysroot/usr/lib/${ANDROID_TOOLCHAIN_NAME}/libc++_shared.so" 321 "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libc++_shared.so" 322 COPYONLY) 323 else() 324 configure_file( 325 "${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${ANDROID_ABI}/libc++_shared.so" 326 "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libc++_shared.so" 327 COPYONLY) 328 endif() 329 endif() 330 # This custom target may be implemented without separate CMake script, but it requires 331 # ADB(Android Debug Bridge) executable file availability, so to incapsulate this requirement 332 # only for corresponding custom target, it was implemented by this way. 333 add_custom_target(device_environment_cleanup COMMAND ${CMAKE_COMMAND} 334 -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/android/device_environment_cleanup.cmake) 335endif() 336 337if (TBB4PY_BUILD) 338 add_subdirectory(python) 339endif() 340 341# Keep it the last instruction. 342add_subdirectory(cmake/post_install) 343