# - Try to find Google performance tools (gperftools) # Input variables: # GPERFTOOLS_ROOT - The gperftools install directory # GPERFTOOLS_INCLUDE - The gperftools include directory # GPERFTOOLS_LIBRARY - The gperftools library directory # Components: profiler, and tcmalloc or tcmalloc_minimal # Output variables: # GPERFTOOLS_FOUND - System has gperftools # GPERFTOOLS_INCLUDE_DIRS - The gperftools include directories # GPERFTOOLS_LIBRARIES - The libraries needed to use gperftools # GPERFTOOLS_VERSION - The version string for gperftools include(FindPackageHandleStandardArgs) if(NOT DEFINED GPERFTOOLS_FOUND) # Check to see if libunwind is required set(GPERFTOOLS_DISABLE_PROFILER FALSE) if((";${Gperftools_FIND_COMPONENTS};" MATCHES ";profiler;") AND (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "BlueGeneQ" OR CMAKE_SYSTEM_NAME MATCHES "BlueGeneP") AND (CMAKE_SIZEOF_VOID_P EQUAL 8)) # Libunwind is required by profiler on this platform if(Gperftools_FIND_REQUIRED_profiler OR Gperftools_FIND_REQUIRED_tcmalloc_and_profiler) find_package(Libunwind 0.99 REQUIRED) else() find_package(Libunwind) if(NOT LIBUNWIND_FOUND OR LIBUNWIND_VERSION VERSION_LESS 0.99) set(GPERFTOOLS_DISABLE_PROFILER TRUE) endif() endif() endif() # Check for invalid components foreach(_comp ${Gperftools_FIND_COMPONENTS}) if((NOT _comp STREQUAL "tcmalloc_and_profiler") AND (NOT _comp STREQUAL "tcmalloc") AND (NOT _comp STREQUAL "tcmalloc_minimal") AND (NOT _comp STREQUAL "profiler")) message(FATAL_ERROR "Invalid component specified for Gperftools: ${_comp}") endif() endforeach() # Check for valid component combinations if(";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc_and_profiler;" AND (";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc;" OR ";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc_minimal;" OR ";${Gperftools_FIND_COMPONENTS};" MATCHES ";profiler;")) message("ERROR: Invalid component selection for Gperftools: ${Gperftools_FIND_COMPONENTS}") message("ERROR: Gperftools cannot link both tcmalloc_and_profiler with the tcmalloc, tcmalloc_minimal, or profiler libraries") message(FATAL_ERROR "Gperftools component list is invalid") endif() if(";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc;" AND ";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc_minimal;") message("ERROR: Invalid component selection for Gperftools: ${Gperftools_FIND_COMPONENTS}") message("ERROR: Gperftools cannot link both tcmalloc and tcmalloc_minimal") message(FATAL_ERROR "Gperftools component list is invalid") endif() # Set default sarch paths for gperftools if(GPERFTOOLS_ROOT) set(GPERFTOOLS_INCLUDE ${GPERFTOOLS_ROOT}/include CACHE PATH "The include directory for gperftools") if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_NAME STREQUAL "Linux") set(GPERFTOOLS_LIBRARY ${GPERFTOOLS_ROOT}/lib64;${GPERFTOOLS_ROOT}/lib CACHE PATH "The library directory for gperftools") else() set(GPERFTOOLS_LIBRARY ${GPERFTOOLS_ROOT}/lib CACHE PATH "The library directory for gperftools") endif() endif() find_path(GPERFTOOLS_INCLUDE_DIRS NAMES gperftools/malloc_extension.h HINTS ${GPERFTOOLS_INCLUDE}) # Search for component libraries foreach(_comp tcmalloc_and_profiler tcmalloc tcmalloc_minimal profiler) find_library(GPERFTOOLS_${_comp}_LIBRARY ${_comp} HINTS ${GPERFTOOLS_LIBRARY}) if(GPERFTOOLS_${_comp}_LIBRARY) set(GPERFTOOLS_${_comp}_FOUND TRUE) else() set(GPERFTOOLS_${_comp}_FOUND FALSE) endif() # Exclude profiler from the found list if libunwind is required but not found if(GPERFTOOLS_${_comp}_FOUND AND ${_comp} MATCHES "profiler" AND GPERFTOOLS_DISABLE_PROFILER) set(GPERFTOOLS_${_comp}_FOUND FALSE) set(GPERFTOOLS_${_comp}_LIBRARY "GPERFTOOLS_${_comp}_LIBRARY-NOTFOUND") message("WARNING: Gperftools '${_comp}' requires libunwind 0.99 or later.") message("WARNING: Gperftools '${_comp}' will be disabled.") endif() if(";${Gperftools_FIND_COMPONENTS};" MATCHES ";${_comp};" AND GPERFTOOLS_${_comp}_FOUND) list(APPEND GPERFTOOLS_LIBRARIES "${GPERFTOOLS_${_comp}_LIBRARY}") endif() endforeach() # Set gperftools libraries if not set based on component list if(NOT GPERFTOOLS_LIBRARIES) if(GPERFTOOLS_tcmalloc_and_profiler_FOUND) set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_and_profiler_LIBRARY}") elseif(GPERFTOOLS_tcmalloc_FOUND AND GPERFTOOLS_profiler_FOUND) set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_LIBRARY}" "${GPERFTOOLS_profiler_LIBRARY}") elseif(GPERFTOOLS_profiler_FOUND) set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_profiler_LIBRARY}") elseif(GPERFTOOLS_tcmalloc_FOUND) set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_LIBRARY}") elseif(GPERFTOOLS_tcmalloc_minimal_FOUND) set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_minimal_LIBRARY}") endif() endif() # handle the QUIETLY and REQUIRED arguments and set GPERFTOOLS_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args(GPERFTOOLS FOUND_VAR GPERFTOOLS_FOUND REQUIRED_VARS GPERFTOOLS_LIBRARIES GPERFTOOLS_INCLUDE_DIRS HANDLE_COMPONENTS) mark_as_advanced(GPERFTOOLS_INCLUDE GPERFTOOLS_LIBRARY GPERFTOOLS_INCLUDE_DIRS GPERFTOOLS_LIBRARIES) # Add linker flags that instruct the compiler to exclude built in memory # allocation functions. This works for GNU, Intel, and Clang. Other compilers # may need to be added in the future. if(GPERFTOOLS_LIBRARIES MATCHES "tcmalloc") if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR ((CMAKE_CXX_COMPILER_ID MATCHES "Intel") AND (NOT CMAKE_CXX_PLATFORM_ID MATCHES "Windows"))) list(APPEND GPERFTOOLS_LIBRARIES "-fno-builtin-malloc" "-fno-builtin-calloc" "-fno-builtin-realloc" "-fno-builtin-free") endif() endif() # Add libunwind flags to gperftools if the profiler is being used if(GPERFTOOLS_LIBRARIES MATCHES "profiler" AND LIBUNWIND_FOUND) list(APPEND GPERFTOOLS_INCLUDE_DIRS "${LIBUNWIND_INCLUDE_DIRS}") list(APPEND GPERFTOOLS_LIBRARIES "${LIBUNWIND_LIBRARIES}") endif() unset(GPERFTOOLS_DISABLE_PROFILER) endif()