diff --git a/CMake/FindTBB.cmake b/CMake/FindTBB.cmake index be1040ab5..497048d45 100644 --- a/CMake/FindTBB.cmake +++ b/CMake/FindTBB.cmake @@ -9,6 +9,7 @@ # TBB_INCLUDE_DIRS - the TBB include directories # TBB_LIBRARIES - TBB libraries to be lined, doesn't include malloc or # malloc proxy +# TBB::tbb - imported target for the TBB library # # TBB_VERSION_MAJOR - Major Product Version Number # TBB_VERSION_MINOR - Minor Product Version Number @@ -20,10 +21,12 @@ # TBB_MALLOC_FOUND - system has TBB malloc library # TBB_MALLOC_INCLUDE_DIRS - the TBB malloc include directories # TBB_MALLOC_LIBRARIES - The TBB malloc libraries to be lined +# TBB::malloc - imported target for the TBB malloc library # # TBB_MALLOC_PROXY_FOUND - system has TBB malloc proxy library # TBB_MALLOC_PROXY_INCLUDE_DIRS = the TBB malloc proxy include directories # TBB_MALLOC_PROXY_LIBRARIES - The TBB malloc proxy libraries to be lined +# TBB::malloc_proxy - imported target for the TBB malloc proxy library # # # This module reads hints about search locations from variables: @@ -65,28 +68,84 @@ # FindTBB helper functions and macros # +#==================================================== +# Fix the library path in case it is a linker script +#==================================================== +function(tbb_extract_real_library library real_library) + if(NOT UNIX OR NOT EXISTS ${library}) + set(${real_library} "${library}" PARENT_SCOPE) + return() + endif() + + #Read in the first 4 bytes and see if they are the ELF magic number + set(_elf_magic "7f454c46") + file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX) + if(_hex_data STREQUAL _elf_magic) + #we have opened a elf binary so this is what + #we should link to + set(${real_library} "${library}" PARENT_SCOPE) + return() + endif() + + file(READ ${library} _data OFFSET 0 LIMIT 1024) + if("${_data}" MATCHES "INPUT \\(([^(]+)\\)") + #extract out the .so name from REGEX MATCH command + set(_proper_so_name "${CMAKE_MATCH_1}") + + #construct path to the real .so which is presumed to be in the same directory + #as the input file + get_filename_component(_so_dir "${library}" DIRECTORY) + set(${real_library} "${_so_dir}/${_proper_so_name}" PARENT_SCOPE) + else() + #unable to determine what this library is so just hope everything works + #and pass it unmodified. + set(${real_library} "${library}" PARENT_SCOPE) + endif() +endfunction() + #=============================================== # Do the final processing for the package find. #=============================================== -macro(findpkg_finish PREFIX) - # skip if already processed during this run - if (NOT ${PREFIX}_FOUND) - if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY) - set(${PREFIX}_FOUND TRUE) - set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR}) - set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY}) - else () - if (${PREFIX}_FIND_REQUIRED AND NOT ${PREFIX}_FIND_QUIETLY) - message(FATAL_ERROR "Required library ${PREFIX} not found.") - endif () +macro(findpkg_finish PREFIX TARGET_NAME) + if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY) + set(${PREFIX}_FOUND TRUE) + set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR}) + set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY}) + else () + if (${PREFIX}_FIND_REQUIRED AND NOT ${PREFIX}_FIND_QUIETLY) + message(FATAL_ERROR "Required library ${PREFIX} not found.") endif () - - #mark the following variables as internal variables - mark_as_advanced(${PREFIX}_INCLUDE_DIR - ${PREFIX}_LIBRARY - ${PREFIX}_LIBRARY_DEBUG - ${PREFIX}_LIBRARY_RELEASE) endif () + + if (NOT TARGET "TBB::${TARGET_NAME}") + if (${PREFIX}_LIBRARY_RELEASE) + tbb_extract_real_library(${${PREFIX}_LIBRARY_RELEASE} real_release) + endif () + if (${PREFIX}_LIBRARY_DEBUG) + tbb_extract_real_library(${${PREFIX}_LIBRARY_DEBUG} real_debug) + endif () + add_library(TBB::${TARGET_NAME} UNKNOWN IMPORTED) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${${PREFIX}_INCLUDE_DIR}") + if (${PREFIX}_LIBRARY_DEBUG AND ${PREFIX}_LIBRARY_RELEASE) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${real_release}" + IMPORTED_LOCATION_DEBUG "${real_debug}" + IMPORTED_LOCATION_RELEASE "${real_release}") + elseif (${PREFIX}_LIBRARY_RELEASE) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${real_release}") + elseif (${PREFIX}_LIBRARY_DEBUG) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${real_debug}") + endif () + endif () + + #mark the following variables as internal variables + mark_as_advanced(${PREFIX}_INCLUDE_DIR + ${PREFIX}_LIBRARY + ${PREFIX}_LIBRARY_DEBUG + ${PREFIX}_LIBRARY_RELEASE) endmacro() #=============================================== @@ -136,20 +195,6 @@ set(TBB_INC_SEARCH_PATH "") set(TBB_LIB_SEARCH_PATH "") -# If we found parts of TBB in a previous pass, add the directories for those -# components to the list of those we look for. -if(TBB_INCLUDE_DIR) - list(APPEND TBB_INC_SEARCH_PATH ${TBB_INCLUDE_DIR}) -endif() - -if(TBB_LIBRARY_RELEASE) - get_filename_component(dir ${TBB_LIBRARY_RELEASE} DIRECTORY) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}) -elseif(TBB_LIBRARY_DEBUG) - get_filename_component(dir ${TBB_LIBRARY_DEBUG} DIRECTORY) - list(APPEND TBB_LIB_SEARCH_PATH ${dir}) -endif() - # If user built from sources set(TBB_BUILD_PREFIX $ENV{TBB_BUILD_PREFIX}) if (TBB_BUILD_PREFIX AND ENV_TBB_ROOT) @@ -203,12 +248,23 @@ if (WIN32 AND MSVC) list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${COMPILER_PREFIX}) endif () endforeach () -elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND - NOT CMAKE_SYSTEM_VERSION VERSION_LESS 13.0) - set (USE_LIBCXX OFF) +endif () - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set (USE_LIBCXX ON) +# For OS X binary distribution, choose libc++ based libraries for Mavericks (10.9) +# and above and AppleClang +if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND + NOT CMAKE_SYSTEM_VERSION VERSION_LESS 13.0) + set (USE_LIBCXX OFF) + cmake_policy(GET CMP0025 POLICY_VAR) + + if (POLICY_VAR STREQUAL "NEW") + if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set (USE_LIBCXX ON) + endif () + else () + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set (USE_LIBCXX ON) + endif () endif () if (USE_LIBCXX) @@ -216,8 +272,10 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND list (APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/libc++ ${dir}/libc++/lib) endforeach () endif () -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # check compiler ABI +endif () + +# check compiler ABI +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(COMPILER_PREFIX) if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) list(APPEND COMPILER_PREFIX "gcc4.7") @@ -285,7 +343,7 @@ find_library(TBB_LIBRARY_DEBUG PATHS ${TBB_LIB_SEARCH_PATH}) make_library_set(TBB_LIBRARY) -findpkg_finish(TBB) +findpkg_finish(TBB tbb) #if we haven't found TBB no point on going any further if (NOT TBB_FOUND) @@ -309,7 +367,7 @@ find_library(TBB_MALLOC_LIBRARY_DEBUG PATHS ${TBB_LIB_SEARCH_PATH}) make_library_set(TBB_MALLOC_LIBRARY) -findpkg_finish(TBB_MALLOC) +findpkg_finish(TBB_MALLOC tbbmalloc) #============================================================================= # Look for TBB's malloc proxy package @@ -328,7 +386,7 @@ find_library(TBB_MALLOC_PROXY_LIBRARY_DEBUG PATHS ${TBB_LIB_SEARCH_PATH}) make_library_set(TBB_MALLOC_PROXY_LIBRARY) -findpkg_finish(TBB_MALLOC_PROXY) +findpkg_finish(TBB_MALLOC_PROXY tbbmalloc_proxy) #============================================================================= @@ -336,10 +394,10 @@ findpkg_finish(TBB_MALLOC_PROXY) if(NOT TBB_VERSION) #only read the start of the file - file(READ + file(STRINGS "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h" TBB_VERSION_CONTENTS - LIMIT 2048) + REGEX "VERSION") string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1"