xref: /oneTBB/CMakeLists.txt (revision fabaaa65)
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