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