2
0

FindTBB.cmake 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  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. # Use TBBConfig.cmake if possible.
  69. set(_tbb_find_quiet)
  70. if (TBB_FIND_QUIETLY)
  71. set(_tbb_find_quiet QUIET)
  72. endif ()
  73. set(_tbb_find_components)
  74. set(_tbb_find_optional_components)
  75. foreach (_tbb_find_component IN LISTS TBB_FIND_COMPONENTS)
  76. if (TBB_FIND_REQUIRED_${_tbb_find_component})
  77. list(APPEND _tbb_find_components "${_tbb_find_component}")
  78. else ()
  79. list(APPEND _tbb_find_optional_components "${_tbb_find_component}")
  80. endif ()
  81. endforeach ()
  82. unset(_tbb_find_component)
  83. find_package(TBB CONFIG ${_tbb_find_quiet}
  84. COMPONENTS ${_tbb_find_components}
  85. OPTIONAL_COMPONENTS ${_tbb_find_optional_components})
  86. unset(_tbb_find_quiet)
  87. unset(_tbb_find_components)
  88. unset(_tbb_find_optional_components)
  89. if (TBB_FOUND)
  90. return ()
  91. endif ()
  92. #====================================================
  93. # Fix the library path in case it is a linker script
  94. #====================================================
  95. function(tbb_extract_real_library library real_library)
  96. if(NOT UNIX OR NOT EXISTS ${library})
  97. set(${real_library} "${library}" PARENT_SCOPE)
  98. return()
  99. endif()
  100. #Read in the first 4 bytes and see if they are the ELF magic number
  101. set(_elf_magic "7f454c46")
  102. file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX)
  103. if(_hex_data STREQUAL _elf_magic)
  104. #we have opened a elf binary so this is what
  105. #we should link to
  106. set(${real_library} "${library}" PARENT_SCOPE)
  107. return()
  108. endif()
  109. file(READ ${library} _data OFFSET 0 LIMIT 1024)
  110. if("${_data}" MATCHES "INPUT \\(([^(]+)\\)")
  111. #extract out the .so name from REGEX MATCH command
  112. set(_proper_so_name "${CMAKE_MATCH_1}")
  113. #construct path to the real .so which is presumed to be in the same directory
  114. #as the input file
  115. get_filename_component(_so_dir "${library}" DIRECTORY)
  116. set(${real_library} "${_so_dir}/${_proper_so_name}" PARENT_SCOPE)
  117. else()
  118. #unable to determine what this library is so just hope everything works
  119. #and pass it unmodified.
  120. set(${real_library} "${library}" PARENT_SCOPE)
  121. endif()
  122. endfunction()
  123. #===============================================
  124. # Do the final processing for the package find.
  125. #===============================================
  126. macro(findpkg_finish PREFIX TARGET_NAME)
  127. if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY)
  128. set(${PREFIX}_FOUND TRUE)
  129. set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR})
  130. set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY})
  131. else ()
  132. if (${PREFIX}_FIND_REQUIRED AND NOT ${PREFIX}_FIND_QUIETLY)
  133. message(FATAL_ERROR "Required library ${PREFIX} not found.")
  134. endif ()
  135. endif ()
  136. if (NOT TARGET "TBB::${TARGET_NAME}")
  137. if (${PREFIX}_LIBRARY_RELEASE)
  138. tbb_extract_real_library(${${PREFIX}_LIBRARY_RELEASE} real_release)
  139. endif ()
  140. if (${PREFIX}_LIBRARY_DEBUG)
  141. tbb_extract_real_library(${${PREFIX}_LIBRARY_DEBUG} real_debug)
  142. endif ()
  143. add_library(TBB::${TARGET_NAME} UNKNOWN IMPORTED)
  144. set_target_properties(TBB::${TARGET_NAME} PROPERTIES
  145. INTERFACE_INCLUDE_DIRECTORIES "${${PREFIX}_INCLUDE_DIR}")
  146. if (${PREFIX}_LIBRARY_DEBUG AND ${PREFIX}_LIBRARY_RELEASE)
  147. set_target_properties(TBB::${TARGET_NAME} PROPERTIES
  148. IMPORTED_LOCATION "${real_release}"
  149. IMPORTED_LOCATION_DEBUG "${real_debug}"
  150. IMPORTED_LOCATION_RELEASE "${real_release}")
  151. elseif (${PREFIX}_LIBRARY_RELEASE)
  152. set_target_properties(TBB::${TARGET_NAME} PROPERTIES
  153. IMPORTED_LOCATION "${real_release}")
  154. elseif (${PREFIX}_LIBRARY_DEBUG)
  155. set_target_properties(TBB::${TARGET_NAME} PROPERTIES
  156. IMPORTED_LOCATION "${real_debug}")
  157. endif ()
  158. endif ()
  159. #mark the following variables as internal variables
  160. mark_as_advanced(${PREFIX}_INCLUDE_DIR
  161. ${PREFIX}_LIBRARY
  162. ${PREFIX}_LIBRARY_DEBUG
  163. ${PREFIX}_LIBRARY_RELEASE)
  164. endmacro()
  165. #===============================================
  166. # Generate debug names from given release names
  167. #===============================================
  168. macro(get_debug_names PREFIX)
  169. foreach(i ${${PREFIX}})
  170. set(${PREFIX}_DEBUG ${${PREFIX}_DEBUG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i})
  171. endforeach()
  172. endmacro()
  173. #===============================================
  174. # See if we have env vars to help us find tbb
  175. #===============================================
  176. macro(getenv_path VAR)
  177. set(ENV_${VAR} $ENV{${VAR}})
  178. # replace won't work if var is blank
  179. if (ENV_${VAR})
  180. string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} )
  181. endif ()
  182. endmacro()
  183. #===============================================
  184. # Couple a set of release AND debug libraries
  185. #===============================================
  186. macro(make_library_set PREFIX)
  187. if (${PREFIX}_RELEASE AND ${PREFIX}_DEBUG)
  188. set(${PREFIX} optimized ${${PREFIX}_RELEASE} debug ${${PREFIX}_DEBUG})
  189. elseif (${PREFIX}_RELEASE)
  190. set(${PREFIX} ${${PREFIX}_RELEASE})
  191. elseif (${PREFIX}_DEBUG)
  192. set(${PREFIX} ${${PREFIX}_DEBUG})
  193. endif ()
  194. endmacro()
  195. #=============================================================================
  196. # Now to actually find TBB
  197. #
  198. # Get path, convert backslashes as ${ENV_${var}}
  199. getenv_path(TBB_ROOT)
  200. # initialize search paths
  201. set(TBB_PREFIX_PATH ${TBB_ROOT} ${ENV_TBB_ROOT})
  202. set(TBB_INC_SEARCH_PATH "")
  203. set(TBB_LIB_SEARCH_PATH "")
  204. # If user built from sources
  205. set(TBB_BUILD_PREFIX $ENV{TBB_BUILD_PREFIX})
  206. if (TBB_BUILD_PREFIX AND ENV_TBB_ROOT)
  207. getenv_path(TBB_BUILD_DIR)
  208. if (NOT ENV_TBB_BUILD_DIR)
  209. set(ENV_TBB_BUILD_DIR ${ENV_TBB_ROOT}/build)
  210. endif ()
  211. # include directory under ${ENV_TBB_ROOT}/include
  212. list(APPEND TBB_LIB_SEARCH_PATH
  213. ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_release
  214. ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_debug)
  215. endif ()
  216. # For Windows, let's assume that the user might be using the precompiled
  217. # TBB packages from the main website. These use a rather awkward directory
  218. # structure (at least for automatically finding the right files) depending
  219. # on platform and compiler, but we'll do our best to accommodate it.
  220. # Not adding the same effort for the precompiled linux builds, though. Those
  221. # have different versions for CC compiler versions and linux kernels which
  222. # will never adequately match the user's setup, so there is no feasible way
  223. # to detect the "best" version to use. The user will have to manually
  224. # select the right files. (Chances are the distributions are shipping their
  225. # custom version of tbb, anyway, so the problem is probably nonexistent.)
  226. if (WIN32 AND MSVC)
  227. set(COMPILER_PREFIX "vc7.1")
  228. if (MSVC_VERSION EQUAL 1400)
  229. set(COMPILER_PREFIX "vc8")
  230. elseif(MSVC_VERSION EQUAL 1500)
  231. set(COMPILER_PREFIX "vc9")
  232. elseif(MSVC_VERSION EQUAL 1600)
  233. set(COMPILER_PREFIX "vc10")
  234. elseif(MSVC_VERSION EQUAL 1700)
  235. set(COMPILER_PREFIX "vc11")
  236. elseif(MSVC_VERSION EQUAL 1800)
  237. set(COMPILER_PREFIX "vc12")
  238. elseif(MSVC_VERSION GREATER_EQUAL 1900)
  239. set(COMPILER_PREFIX "vc14")
  240. endif ()
  241. # for each prefix path, add ia32/64\${COMPILER_PREFIX}\lib to the lib search path
  242. foreach (dir IN LISTS TBB_PREFIX_PATH)
  243. if (CMAKE_CL_64)
  244. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia64/${COMPILER_PREFIX}/lib)
  245. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia64/${COMPILER_PREFIX})
  246. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${COMPILER_PREFIX}/lib)
  247. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${COMPILER_PREFIX})
  248. else ()
  249. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${COMPILER_PREFIX}/lib)
  250. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${COMPILER_PREFIX})
  251. endif ()
  252. endforeach ()
  253. endif ()
  254. # For OS X binary distribution, choose libc++ based libraries for Mavericks (10.9)
  255. # and above and AppleClang
  256. if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND
  257. NOT CMAKE_SYSTEM_VERSION VERSION_LESS 13.0)
  258. set (USE_LIBCXX OFF)
  259. cmake_policy(GET CMP0025 POLICY_VAR)
  260. if (POLICY_VAR STREQUAL "NEW")
  261. if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
  262. set (USE_LIBCXX ON)
  263. endif ()
  264. else ()
  265. if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  266. set (USE_LIBCXX ON)
  267. endif ()
  268. endif ()
  269. if (USE_LIBCXX)
  270. foreach (dir IN LISTS TBB_PREFIX_PATH)
  271. list (APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/libc++ ${dir}/libc++/lib)
  272. endforeach ()
  273. endif ()
  274. endif ()
  275. # check compiler ABI
  276. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  277. set(COMPILER_PREFIX)
  278. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
  279. list(APPEND COMPILER_PREFIX "gcc4.8")
  280. endif()
  281. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
  282. list(APPEND COMPILER_PREFIX "gcc4.7")
  283. endif()
  284. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
  285. list(APPEND COMPILER_PREFIX "gcc4.4")
  286. endif()
  287. list(APPEND COMPILER_PREFIX "gcc4.1")
  288. elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  289. set(COMPILER_PREFIX)
  290. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) # Complete guess
  291. list(APPEND COMPILER_PREFIX "gcc4.8")
  292. endif()
  293. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6)
  294. list(APPEND COMPILER_PREFIX "gcc4.7")
  295. endif()
  296. list(APPEND COMPILER_PREFIX "gcc4.4")
  297. else() # Assume compatibility with 4.4 for other compilers
  298. list(APPEND COMPILER_PREFIX "gcc4.4")
  299. endif ()
  300. # if platform architecture is explicitly specified
  301. set(TBB_ARCH_PLATFORM $ENV{TBB_ARCH_PLATFORM})
  302. if (TBB_ARCH_PLATFORM)
  303. foreach (dir IN LISTS TBB_PREFIX_PATH)
  304. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/${TBB_ARCH_PLATFORM}/lib)
  305. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/${TBB_ARCH_PLATFORM})
  306. endforeach ()
  307. endif ()
  308. foreach (dir IN LISTS TBB_PREFIX_PATH)
  309. foreach (prefix IN LISTS COMPILER_PREFIX)
  310. if (CMAKE_SIZEOF_VOID_P EQUAL 8)
  311. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64)
  312. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${prefix})
  313. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/lib)
  314. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${prefix}/lib)
  315. else ()
  316. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32)
  317. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${prefix})
  318. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/lib)
  319. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${prefix}/lib)
  320. endif ()
  321. endforeach()
  322. endforeach ()
  323. # add general search paths
  324. foreach (dir IN LISTS TBB_PREFIX_PATH)
  325. list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib ${dir}/Lib ${dir}/lib/tbb
  326. ${dir}/Libs)
  327. list(APPEND TBB_INC_SEARCH_PATH ${dir}/include ${dir}/Include
  328. ${dir}/include/tbb)
  329. endforeach ()
  330. set(TBB_LIBRARY_NAMES tbb)
  331. get_debug_names(TBB_LIBRARY_NAMES)
  332. find_path(TBB_INCLUDE_DIR
  333. NAMES tbb/tbb.h
  334. PATHS ${TBB_INC_SEARCH_PATH})
  335. find_library(TBB_LIBRARY_RELEASE
  336. NAMES ${TBB_LIBRARY_NAMES}
  337. PATHS ${TBB_LIB_SEARCH_PATH})
  338. find_library(TBB_LIBRARY_DEBUG
  339. NAMES ${TBB_LIBRARY_NAMES_DEBUG}
  340. PATHS ${TBB_LIB_SEARCH_PATH})
  341. make_library_set(TBB_LIBRARY)
  342. findpkg_finish(TBB tbb)
  343. #if we haven't found TBB no point on going any further
  344. if (NOT TBB_FOUND)
  345. return()
  346. endif ()
  347. #=============================================================================
  348. # Look for TBB's malloc package
  349. set(TBB_MALLOC_LIBRARY_NAMES tbbmalloc)
  350. get_debug_names(TBB_MALLOC_LIBRARY_NAMES)
  351. find_path(TBB_MALLOC_INCLUDE_DIR
  352. NAMES tbb/tbb.h
  353. PATHS ${TBB_INC_SEARCH_PATH})
  354. find_library(TBB_MALLOC_LIBRARY_RELEASE
  355. NAMES ${TBB_MALLOC_LIBRARY_NAMES}
  356. PATHS ${TBB_LIB_SEARCH_PATH})
  357. find_library(TBB_MALLOC_LIBRARY_DEBUG
  358. NAMES ${TBB_MALLOC_LIBRARY_NAMES_DEBUG}
  359. PATHS ${TBB_LIB_SEARCH_PATH})
  360. make_library_set(TBB_MALLOC_LIBRARY)
  361. findpkg_finish(TBB_MALLOC tbbmalloc)
  362. #=============================================================================
  363. # Look for TBB's malloc proxy package
  364. set(TBB_MALLOC_PROXY_LIBRARY_NAMES tbbmalloc_proxy)
  365. get_debug_names(TBB_MALLOC_PROXY_LIBRARY_NAMES)
  366. find_path(TBB_MALLOC_PROXY_INCLUDE_DIR
  367. NAMES tbb/tbbmalloc_proxy.h
  368. PATHS ${TBB_INC_SEARCH_PATH})
  369. find_library(TBB_MALLOC_PROXY_LIBRARY_RELEASE
  370. NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES}
  371. PATHS ${TBB_LIB_SEARCH_PATH})
  372. find_library(TBB_MALLOC_PROXY_LIBRARY_DEBUG
  373. NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES_DEBUG}
  374. PATHS ${TBB_LIB_SEARCH_PATH})
  375. make_library_set(TBB_MALLOC_PROXY_LIBRARY)
  376. findpkg_finish(TBB_MALLOC_PROXY tbbmalloc_proxy)
  377. #=============================================================================
  378. #parse all the version numbers from tbb
  379. if(NOT TBB_VERSION)
  380. if (EXISTS "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h")
  381. file(STRINGS
  382. "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h"
  383. TBB_VERSION_CONTENTS
  384. REGEX "VERSION")
  385. else()
  386. #only read the start of the file
  387. file(STRINGS
  388. "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h"
  389. TBB_VERSION_CONTENTS
  390. REGEX "VERSION")
  391. endif()
  392. string(REGEX REPLACE
  393. ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1"
  394. TBB_VERSION_MAJOR "${TBB_VERSION_CONTENTS}")
  395. string(REGEX REPLACE
  396. ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1"
  397. TBB_VERSION_MINOR "${TBB_VERSION_CONTENTS}")
  398. string(REGEX REPLACE
  399. ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1"
  400. TBB_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}")
  401. string(REGEX REPLACE
  402. ".*#define TBB_COMPATIBLE_INTERFACE_VERSION ([0-9]+).*" "\\1"
  403. TBB_COMPATIBLE_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}")
  404. endif()