FindTBB.cmake 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. # - Find ThreadingBuildingBlocks include dirs and libraries
  2. # Use this module by invoking find_package with the form:
  3. # find_package(TBB
  4. # [REQUIRED] # Fail with error if TBB is not found
  5. # ) #
  6. # Once done, this will define
  7. #
  8. # TBB_FOUND - system has TBB
  9. # TBB_INCLUDE_DIRS - the TBB include directories
  10. # TBB_LIBRARIES - TBB libraries to be lined, doesn't include malloc or
  11. # malloc proxy
  12. # TBB::tbb - imported target for the TBB library
  13. #
  14. # TBB_VERSION_MAJOR - Major Product Version Number
  15. # TBB_VERSION_MINOR - Minor Product Version Number
  16. # TBB_INTERFACE_VERSION - Engineering Focused Version Number
  17. # TBB_COMPATIBLE_INTERFACE_VERSION - The oldest major interface version
  18. # still supported. This uses the engineering
  19. # focused interface version numbers.
  20. #
  21. # TBB_MALLOC_FOUND - system has TBB malloc library
  22. # TBB_MALLOC_INCLUDE_DIRS - the TBB malloc include directories
  23. # TBB_MALLOC_LIBRARIES - The TBB malloc libraries to be lined
  24. # TBB::malloc - imported target for the TBB malloc library
  25. #
  26. # TBB_MALLOC_PROXY_FOUND - system has TBB malloc proxy library
  27. # TBB_MALLOC_PROXY_INCLUDE_DIRS = the TBB malloc proxy include directories
  28. # TBB_MALLOC_PROXY_LIBRARIES - The TBB malloc proxy libraries to be lined
  29. # TBB::malloc_proxy - imported target for the TBB malloc proxy library
  30. #
  31. #
  32. # This module reads hints about search locations from variables:
  33. # ENV TBB_ARCH_PLATFORM - for eg. set it to "mic" for Xeon Phi builds
  34. # ENV TBB_ROOT or just TBB_ROOT - root directory of tbb installation
  35. # ENV TBB_BUILD_PREFIX - specifies the build prefix for user built tbb
  36. # libraries. Should be specified with ENV TBB_ROOT
  37. # and optionally...
  38. # ENV TBB_BUILD_DIR - if build directory is different than ${TBB_ROOT}/build
  39. #
  40. #
  41. # Modified by Robert Maynard from the original OGRE source
  42. #
  43. #-------------------------------------------------------------------
  44. # This file is part of the CMake build system for OGRE
  45. # (Object-oriented Graphics Rendering Engine)
  46. # For the latest info, see http://www.ogre3d.org/
  47. #
  48. # The contents of this file are placed in the public domain. Feel
  49. # free to make use of it in any way you like.
  50. #-------------------------------------------------------------------
  51. #
  52. #=============================================================================
  53. # Copyright 2010-2012 Kitware, Inc.
  54. # Copyright 2012 Rolf Eike Beer <[email protected]>
  55. #
  56. # Distributed under the OSI-approved BSD License (the "License");
  57. # see accompanying file Copyright.txt for details.
  58. #
  59. # This software is distributed WITHOUT ANY WARRANTY; without even the
  60. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  61. # See the License for more information.
  62. #=============================================================================
  63. # (To distribute this file outside of CMake, substitute the full
  64. # License text for the above reference.)
  65. #=============================================================================
  66. # FindTBB helper functions and macros
  67. #
  68. message("** Looking for TBB...")
  69. # Use TBBConfig.cmake if possible.
  70. set(_tbb_find_quiet)
  71. if (TBB_FIND_QUIETLY)
  72. set(_tbb_find_quiet QUIET)
  73. endif ()
  74. set(_tbb_find_components)
  75. set(_tbb_find_optional_components)
  76. foreach (_tbb_find_component IN LISTS TBB_FIND_COMPONENTS)
  77. if (TBB_FIND_REQUIRED_${_tbb_find_component})
  78. list(APPEND _tbb_find_components "${_tbb_find_component}")
  79. else ()
  80. list(APPEND _tbb_find_optional_components "${_tbb_find_component}")
  81. endif ()
  82. endforeach ()
  83. unset(_tbb_find_component)
  84. find_package(TBB CONFIG ${_tbb_find_quiet}
  85. COMPONENTS ${_tbb_find_components}
  86. OPTIONAL_COMPONENTS ${_tbb_find_optional_components})
  87. unset(_tbb_find_quiet)
  88. unset(_tbb_find_components)
  89. unset(_tbb_find_optional_components)
  90. set(TBB_LIBRARIES ${TBB_IMPORTED_TARGETS})
  91. if (TBB_FOUND)
  92. return ()
  93. endif ()
  94. #====================================================
  95. # Fix the library path in case it is a linker script
  96. #====================================================
  97. function(tbb_extract_real_library library real_library)
  98. if(NOT UNIX OR NOT EXISTS ${library})
  99. set(${real_library} "${library}" PARENT_SCOPE)
  100. return()
  101. endif()
  102. #Read in the first 4 bytes and see if they are the ELF magic number
  103. set(_elf_magic "7f454c46")
  104. file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX)
  105. if(_hex_data STREQUAL _elf_magic)
  106. #we have opened a elf binary so this is what
  107. #we should link to
  108. set(${real_library} "${library}" PARENT_SCOPE)
  109. return()
  110. endif()
  111. file(READ ${library} _data OFFSET 0 LIMIT 1024)
  112. if("${_data}" MATCHES "INPUT \\(([^(]+)\\)")
  113. #extract out the .so name from REGEX MATCH command
  114. set(_proper_so_name "${CMAKE_MATCH_1}")
  115. #construct path to the real .so which is presumed to be in the same directory
  116. #as the input file
  117. get_filename_component(_so_dir "${library}" DIRECTORY)
  118. set(${real_library} "${_so_dir}/${_proper_so_name}" PARENT_SCOPE)
  119. else()
  120. #unable to determine what this library is so just hope everything works
  121. #and pass it unmodified.
  122. set(${real_library} "${library}" PARENT_SCOPE)
  123. endif()
  124. endfunction()
  125. #===============================================
  126. # Do the final processing for the package find.
  127. #===============================================
  128. macro(findpkg_finish PREFIX TARGET_NAME)
  129. if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY)
  130. set(${PREFIX}_FOUND TRUE)
  131. set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR})
  132. set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY})
  133. else ()
  134. if (${PREFIX}_FIND_REQUIRED AND NOT ${PREFIX}_FIND_QUIETLY)
  135. message(FATAL_ERROR "Required library ${PREFIX} not found.")
  136. endif ()
  137. endif ()
  138. if (NOT TARGET "TBB::${TARGET_NAME}")
  139. if (${PREFIX}_LIBRARY_RELEASE)
  140. tbb_extract_real_library(${${PREFIX}_LIBRARY_RELEASE} real_release)
  141. endif ()
  142. if (${PREFIX}_LIBRARY_DEBUG)
  143. tbb_extract_real_library(${${PREFIX}_LIBRARY_DEBUG} real_debug)
  144. endif ()
  145. add_library(TBB::${TARGET_NAME} UNKNOWN IMPORTED)
  146. set_target_properties(TBB::${TARGET_NAME} PROPERTIES
  147. INTERFACE_INCLUDE_DIRECTORIES "${${PREFIX}_INCLUDE_DIR}")
  148. if (${PREFIX}_LIBRARY_DEBUG AND ${PREFIX}_LIBRARY_RELEASE)
  149. set_target_properties(TBB::${TARGET_NAME} PROPERTIES
  150. IMPORTED_LOCATION "${real_release}"
  151. IMPORTED_LOCATION_DEBUG "${real_debug}"
  152. IMPORTED_LOCATION_RELEASE "${real_release}")
  153. elseif (${PREFIX}_LIBRARY_RELEASE)
  154. set_target_properties(TBB::${TARGET_NAME} PROPERTIES
  155. IMPORTED_LOCATION "${real_release}")
  156. elseif (${PREFIX}_LIBRARY_DEBUG)
  157. set_target_properties(TBB::${TARGET_NAME} PROPERTIES
  158. IMPORTED_LOCATION "${real_debug}")
  159. endif ()
  160. endif ()
  161. #mark the following variables as internal variables
  162. mark_as_advanced(${PREFIX}_INCLUDE_DIR
  163. ${PREFIX}_LIBRARY
  164. ${PREFIX}_LIBRARY_DEBUG
  165. ${PREFIX}_LIBRARY_RELEASE)
  166. endmacro()
  167. #===============================================
  168. # Generate debug names from given release names
  169. #===============================================
  170. macro(get_debug_names PREFIX)
  171. foreach(i ${${PREFIX}})
  172. set(${PREFIX}_DEBUG ${${PREFIX}_DEBUG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i})
  173. endforeach()
  174. endmacro()
  175. #===============================================
  176. # See if we have env vars to help us find tbb
  177. #===============================================
  178. macro(getenv_path VAR)
  179. set(ENV_${VAR} $ENV{${VAR}})
  180. # replace won't work if var is blank
  181. if (ENV_${VAR})
  182. string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} )
  183. endif ()
  184. endmacro()
  185. #===============================================
  186. # Couple a set of release AND debug libraries
  187. #===============================================
  188. macro(make_library_set PREFIX)
  189. if (${PREFIX}_RELEASE AND ${PREFIX}_DEBUG)
  190. set(${PREFIX} optimized ${${PREFIX}_RELEASE} debug ${${PREFIX}_DEBUG})
  191. elseif (${PREFIX}_RELEASE)
  192. set(${PREFIX} ${${PREFIX}_RELEASE})
  193. elseif (${PREFIX}_DEBUG)
  194. set(${PREFIX} ${${PREFIX}_DEBUG})
  195. endif ()
  196. endmacro()
  197. #=============================================================================
  198. # Now to actually find TBB
  199. #
  200. # Get path, convert backslashes as ${ENV_${var}}
  201. getenv_path(TBB_ROOT)
  202. # initialize search paths
  203. set(TBB_PREFIX_PATH ${TBB_ROOT} ${ENV_TBB_ROOT})
  204. set(TBB_INC_SEARCH_PATH "")
  205. set(TBB_LIB_SEARCH_PATH "")
  206. # If user built from sources
  207. set(TBB_BUILD_PREFIX $ENV{TBB_BUILD_PREFIX})
  208. if (TBB_BUILD_PREFIX AND ENV_TBB_ROOT)
  209. getenv_path(TBB_BUILD_DIR)
  210. if (NOT ENV_TBB_BUILD_DIR)
  211. set(ENV_TBB_BUILD_DIR ${ENV_TBB_ROOT}/build)
  212. endif ()
  213. # include directory under ${ENV_TBB_ROOT}/include
  214. list(APPEND TBB_LIB_SEARCH_PATH
  215. ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_release
  216. ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_debug)
  217. endif ()
  218. # For Windows, let's assume that the user might be using the precompiled
  219. # TBB packages from the main website. These use a rather awkward directory
  220. # structure (at least for automatically finding the right files) depending
  221. # on platform and compiler, but we'll do our best to accommodate it.
  222. # Not adding the same effort for the precompiled linux builds, though. Those
  223. # have different versions for CC compiler versions and linux kernels which
  224. # will never adequately match the user's setup, so there is no feasible way
  225. # to detect the "best" version to use. The user will have to manually
  226. # select the right files. (Chances are the distributions are shipping their
  227. # custom version of tbb, anyway, so the problem is probably nonexistent.)
  228. if (WIN32 AND MSVC)
  229. set(COMPILER_PREFIX "vc7.1")
  230. if (MSVC_VERSION EQUAL 1400)
  231. set(COMPILER_PREFIX "vc8")
  232. elseif(MSVC_VERSION EQUAL 1500)
  233. set(COMPILER_PREFIX "vc9")
  234. elseif(MSVC_VERSION EQUAL 1600)
  235. set(COMPILER_PREFIX "vc10")
  236. elseif(MSVC_VERSION EQUAL 1700)
  237. set(COMPILER_PREFIX "vc11")
  238. elseif(MSVC_VERSION EQUAL 1800)
  239. set(COMPILER_PREFIX "vc12")
  240. elseif(MSVC_VERSION GREATER_EQUAL 1900)
  241. set(COMPILER_PREFIX "vc14")
  242. endif ()
  243. # for each prefix path, add ia32/64\${COMPILER_PREFIX}\lib to the lib search path
  244. foreach (dir IN LISTS TBB_PREFIX_PATH)
  245. if (CMAKE_CL_64)
  246. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia64/${COMPILER_PREFIX}/lib)
  247. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia64/${COMPILER_PREFIX})
  248. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${COMPILER_PREFIX}/lib)
  249. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${COMPILER_PREFIX})
  250. else ()
  251. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${COMPILER_PREFIX}/lib)
  252. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${COMPILER_PREFIX})
  253. endif ()
  254. endforeach ()
  255. endif ()
  256. # For OS X binary distribution, choose libc++ based libraries for Mavericks (10.9)
  257. # and above and AppleClang
  258. if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND
  259. NOT CMAKE_SYSTEM_VERSION VERSION_LESS 13.0)
  260. set (USE_LIBCXX OFF)
  261. cmake_policy(GET CMP0025 POLICY_VAR)
  262. if (POLICY_VAR STREQUAL "NEW")
  263. if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
  264. set (USE_LIBCXX ON)
  265. endif ()
  266. else ()
  267. if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  268. set (USE_LIBCXX ON)
  269. endif ()
  270. endif ()
  271. if (USE_LIBCXX)
  272. foreach (dir IN LISTS TBB_PREFIX_PATH)
  273. list (APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/libc++ ${dir}/libc++/lib)
  274. endforeach ()
  275. endif ()
  276. endif ()
  277. # check compiler ABI
  278. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  279. set(COMPILER_PREFIX)
  280. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
  281. list(APPEND COMPILER_PREFIX "gcc4.8")
  282. endif()
  283. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
  284. list(APPEND COMPILER_PREFIX "gcc4.7")
  285. endif()
  286. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
  287. list(APPEND COMPILER_PREFIX "gcc4.4")
  288. endif()
  289. list(APPEND COMPILER_PREFIX "gcc4.1")
  290. elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  291. set(COMPILER_PREFIX)
  292. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) # Complete guess
  293. list(APPEND COMPILER_PREFIX "gcc4.8")
  294. endif()
  295. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6)
  296. list(APPEND COMPILER_PREFIX "gcc4.7")
  297. endif()
  298. list(APPEND COMPILER_PREFIX "gcc4.4")
  299. else() # Assume compatibility with 4.4 for other compilers
  300. list(APPEND COMPILER_PREFIX "gcc4.4")
  301. endif ()
  302. # if platform architecture is explicitly specified
  303. set(TBB_ARCH_PLATFORM $ENV{TBB_ARCH_PLATFORM})
  304. if (TBB_ARCH_PLATFORM)
  305. foreach (dir IN LISTS TBB_PREFIX_PATH)
  306. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/${TBB_ARCH_PLATFORM}/lib)
  307. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/${TBB_ARCH_PLATFORM})
  308. endforeach ()
  309. endif ()
  310. foreach (dir IN LISTS TBB_PREFIX_PATH)
  311. foreach (prefix IN LISTS COMPILER_PREFIX)
  312. if (CMAKE_SIZEOF_VOID_P EQUAL 8)
  313. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64)
  314. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${prefix})
  315. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/lib)
  316. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${prefix}/lib)
  317. else ()
  318. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32)
  319. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${prefix})
  320. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/lib)
  321. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${prefix}/lib)
  322. endif ()
  323. endforeach()
  324. endforeach ()
  325. # add general search paths
  326. foreach (dir IN LISTS TBB_PREFIX_PATH)
  327. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib ${dir}/Lib ${dir}/lib/tbb
  328. ${dir}/Libs)
  329. list(APPEND TBB_INC_SEARCH_PATH ${dir}/include ${dir}/Include
  330. ${dir}/include/tbb)
  331. endforeach ()
  332. set(TBB_LIBRARY_NAMES tbb)
  333. get_debug_names(TBB_LIBRARY_NAMES)
  334. find_path(TBB_INCLUDE_DIR
  335. NAMES tbb/tbb_stddef.h
  336. PATHS ${TBB_INC_SEARCH_PATH})
  337. find_library(TBB_LIBRARY_RELEASE
  338. NAMES ${TBB_LIBRARY_NAMES}
  339. PATHS ${TBB_LIB_SEARCH_PATH})
  340. find_library(TBB_LIBRARY_DEBUG
  341. NAMES ${TBB_LIBRARY_NAMES_DEBUG}
  342. PATHS ${TBB_LIB_SEARCH_PATH})
  343. make_library_set(TBB_LIBRARY)
  344. findpkg_finish(TBB tbb)
  345. #if we haven't found TBB no point on going any further
  346. if (NOT TBB_FOUND)
  347. return()
  348. endif ()
  349. #=============================================================================
  350. # Look for TBB's malloc package
  351. set(TBB_MALLOC_LIBRARY_NAMES tbbmalloc)
  352. get_debug_names(TBB_MALLOC_LIBRARY_NAMES)
  353. find_path(TBB_MALLOC_INCLUDE_DIR
  354. NAMES tbb/tbb.h
  355. PATHS ${TBB_INC_SEARCH_PATH})
  356. find_library(TBB_MALLOC_LIBRARY_RELEASE
  357. NAMES ${TBB_MALLOC_LIBRARY_NAMES}
  358. PATHS ${TBB_LIB_SEARCH_PATH})
  359. find_library(TBB_MALLOC_LIBRARY_DEBUG
  360. NAMES ${TBB_MALLOC_LIBRARY_NAMES_DEBUG}
  361. PATHS ${TBB_LIB_SEARCH_PATH})
  362. make_library_set(TBB_MALLOC_LIBRARY)
  363. findpkg_finish(TBB_MALLOC tbbmalloc)
  364. #=============================================================================
  365. # Look for TBB's malloc proxy package
  366. set(TBB_MALLOC_PROXY_LIBRARY_NAMES tbbmalloc_proxy)
  367. get_debug_names(TBB_MALLOC_PROXY_LIBRARY_NAMES)
  368. find_path(TBB_MALLOC_PROXY_INCLUDE_DIR
  369. NAMES tbb/tbbmalloc_proxy.h
  370. PATHS ${TBB_INC_SEARCH_PATH})
  371. find_library(TBB_MALLOC_PROXY_LIBRARY_RELEASE
  372. NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES}
  373. PATHS ${TBB_LIB_SEARCH_PATH})
  374. find_library(TBB_MALLOC_PROXY_LIBRARY_DEBUG
  375. NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES_DEBUG}
  376. PATHS ${TBB_LIB_SEARCH_PATH})
  377. make_library_set(TBB_MALLOC_PROXY_LIBRARY)
  378. findpkg_finish(TBB_MALLOC_PROXY tbbmalloc_proxy)
  379. #=============================================================================
  380. #parse all the version numbers from tbb
  381. if(NOT TBB_VERSION)
  382. if (EXISTS "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h")
  383. file(STRINGS
  384. "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h"
  385. TBB_VERSION_CONTENTS
  386. REGEX "VERSION")
  387. else()
  388. #only read the start of the file
  389. file(STRINGS
  390. "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h"
  391. TBB_VERSION_CONTENTS
  392. REGEX "VERSION")
  393. endif()
  394. string(REGEX REPLACE
  395. ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1"
  396. TBB_VERSION_MAJOR "${TBB_VERSION_CONTENTS}")
  397. string(REGEX REPLACE
  398. ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1"
  399. TBB_VERSION_MINOR "${TBB_VERSION_CONTENTS}")
  400. string(REGEX REPLACE
  401. ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1"
  402. TBB_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}")
  403. string(REGEX REPLACE
  404. ".*#define TBB_COMPATIBLE_INTERFACE_VERSION ([0-9]+).*" "\\1"
  405. TBB_COMPATIBLE_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}")
  406. endif()