FindTBB.cmake 15 KB

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