|
| 1 | +# This file is part of MADNESS |
| 2 | +# https://github.com/m-a-d-n-e-s-s/madness/blob/master/cmake/modules/FindGperftools.cmake |
| 3 | +# |
| 4 | +# - Try to find Google performance tools (gperftools) |
| 5 | +# Input variables: |
| 6 | +# GPERFTOOLS_ROOT_DIR - The gperftools install directory |
| 7 | +# GPERFTOOLS_INCLUDE_DIR - The gperftools include directory |
| 8 | +# GPERFTOOLS_LIBRARY - The gperftools library directory |
| 9 | +# Components: profiler, and tcmalloc or tcmalloc_minimal |
| 10 | +# Output variables: |
| 11 | +# GPERFTOOLS_FOUND - System has gperftools |
| 12 | +# GPERFTOOLS_INCLUDE_DIRS - The gperftools include directories |
| 13 | +# GPERFTOOLS_LIBRARIES - The libraries needed to use gperftools |
| 14 | +# GPERFTOOLS_VERSION - The version string for gperftools |
| 15 | + |
| 16 | +include(FindPackageHandleStandardArgs) |
| 17 | + |
| 18 | +if(NOT DEFINED GPERFTOOLS_FOUND) |
| 19 | + |
| 20 | + # Check to see if libunwind is required |
| 21 | + set(GPERFTOOLS_DISABLE_PROFILER FALSE) |
| 22 | + if((";${Gperftools_FIND_COMPONENTS};" MATCHES ";profiler;") AND |
| 23 | + (CMAKE_SYSTEM_NAME MATCHES "Linux" OR |
| 24 | + CMAKE_SYSTEM_NAME MATCHES "BlueGeneQ" OR |
| 25 | + CMAKE_SYSTEM_NAME MATCHES "BlueGeneP") AND |
| 26 | + (CMAKE_SIZEOF_VOID_P EQUAL 8)) |
| 27 | + |
| 28 | + # Libunwind is required by profiler on this platform |
| 29 | + if(Gperftools_FIND_REQUIRED_profiler OR Gperftools_FIND_REQUIRED_tcmalloc_and_profiler) |
| 30 | + find_package(Libunwind 0.99 REQUIRED) |
| 31 | + else() |
| 32 | + find_package(Libunwind) |
| 33 | + if(NOT LIBUNWIND_FOUND OR LIBUNWIND_VERSION VERSION_LESS 0.99) |
| 34 | + set(GPERFTOOLS_DISABLE_PROFILER TRUE) |
| 35 | + endif() |
| 36 | + endif() |
| 37 | + endif() |
| 38 | + |
| 39 | + # Check for invalid components |
| 40 | + foreach(_comp ${Gperftools_FIND_COMPONENTS}) |
| 41 | + if((NOT _comp STREQUAL "tcmalloc_and_profiler") AND |
| 42 | + (NOT _comp STREQUAL "tcmalloc") AND |
| 43 | + (NOT _comp STREQUAL "tcmalloc_minimal") AND |
| 44 | + (NOT _comp STREQUAL "profiler")) |
| 45 | + message(FATAL_ERROR "Invalid component specified for Gperftools: ${_comp}") |
| 46 | + endif() |
| 47 | + endforeach() |
| 48 | + |
| 49 | + # Check for valid component combinations |
| 50 | + if(";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc_and_profiler;" AND |
| 51 | + (";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc;" OR |
| 52 | + ";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc_minimal;" OR |
| 53 | + ";${Gperftools_FIND_COMPONENTS};" MATCHES ";profiler;")) |
| 54 | + message("ERROR: Invalid component selection for Gperftools: ${Gperftools_FIND_COMPONENTS}") |
| 55 | + message("ERROR: Gperftools cannot link both tcmalloc_and_profiler with the tcmalloc, tcmalloc_minimal, or profiler libraries") |
| 56 | + message(FATAL_ERROR "Gperftools component list is invalid") |
| 57 | + endif() |
| 58 | + if(";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc;" AND ";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc_minimal;") |
| 59 | + message("ERROR: Invalid component selection for Gperftools: ${Gperftools_FIND_COMPONENTS}") |
| 60 | + message("ERROR: Gperftools cannot link both tcmalloc and tcmalloc_minimal") |
| 61 | + message(FATAL_ERROR "Gperftools component list is invalid") |
| 62 | + endif() |
| 63 | + |
| 64 | + # Set default sarch paths for gperftools |
| 65 | + if(GPERFTOOLS_ROOT_DIR) |
| 66 | + set(GPERFTOOLS_INCLUDE_DIR ${GPERFTOOLS_ROOT_DIR}/include CACHE PATH "The include directory for gperftools") |
| 67 | + if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_NAME STREQUAL "Linux") |
| 68 | + set(GPERFTOOLS_LIBRARY ${GPERFTOOLS_ROOT_DIR}/lib64;${GPERFTOOLS_ROOT_DIR}/lib CACHE PATH "The library directory for gperftools") |
| 69 | + else() |
| 70 | + set(GPERFTOOLS_LIBRARY ${GPERFTOOLS_ROOT_DIR}/lib CACHE PATH "The library directory for gperftools") |
| 71 | + endif() |
| 72 | + endif() |
| 73 | + |
| 74 | + find_path(GPERFTOOLS_INCLUDE_DIRS NAMES gperftools/malloc_extension.h |
| 75 | + HINTS ${GPERFTOOLS_INCLUDE_DIR}) |
| 76 | + |
| 77 | + # Search for component libraries |
| 78 | + foreach(_comp tcmalloc_and_profiler tcmalloc tcmalloc_minimal profiler) |
| 79 | + find_library(GPERFTOOLS_${_comp}_LIBRARY ${_comp} |
| 80 | + HINTS ${GPERFTOOLS_LIBRARY}) |
| 81 | + if(GPERFTOOLS_${_comp}_LIBRARY) |
| 82 | + set(GPERFTOOLS_${_comp}_FOUND TRUE) |
| 83 | + else() |
| 84 | + set(GPERFTOOLS_${_comp}_FOUND FALSE) |
| 85 | + endif() |
| 86 | + |
| 87 | + # Exclude profiler from the found list if libunwind is required but not found |
| 88 | + if(GPERFTOOLS_${_comp}_FOUND AND ${_comp} MATCHES "profiler" AND GPERFTOOLS_DISABLE_PROFILER) |
| 89 | + set(GPERFTOOLS_${_comp}_FOUND FALSE) |
| 90 | + set(GPERFTOOLS_${_comp}_LIBRARY "GPERFTOOLS_${_comp}_LIBRARY-NOTFOUND") |
| 91 | + message("WARNING: Gperftools '${_comp}' requires libunwind 0.99 or later.") |
| 92 | + message("WARNING: Gperftools '${_comp}' will be disabled.") |
| 93 | + endif() |
| 94 | + |
| 95 | + if(";${Gperftools_FIND_COMPONENTS};" MATCHES ";${_comp};" AND GPERFTOOLS_${_comp}_FOUND) |
| 96 | + list(APPEND GPERFTOOLS_LIBRARIES "${GPERFTOOLS_${_comp}_LIBRARY}") |
| 97 | + endif() |
| 98 | + endforeach() |
| 99 | + |
| 100 | + # Set gperftools libraries if not set based on component list |
| 101 | + if(NOT GPERFTOOLS_LIBRARIES) |
| 102 | + if(GPERFTOOLS_tcmalloc_and_profiler_FOUND) |
| 103 | + set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_and_profiler_LIBRARY}") |
| 104 | + elseif(GPERFTOOLS_tcmalloc_FOUND AND GPERFTOOLS_profiler_FOUND) |
| 105 | + set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_LIBRARY}" "${GPERFTOOLS_profiler_LIBRARY}") |
| 106 | + elseif(GPERFTOOLS_profiler_FOUND) |
| 107 | + set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_profiler_LIBRARY}") |
| 108 | + elseif(GPERFTOOLS_tcmalloc_FOUND) |
| 109 | + set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_LIBRARY}") |
| 110 | + elseif(GPERFTOOLS_tcmalloc_minimal_FOUND) |
| 111 | + set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_minimal_LIBRARY}") |
| 112 | + endif() |
| 113 | + endif() |
| 114 | + |
| 115 | + # handle the QUIETLY and REQUIRED arguments and set GPERFTOOLS_FOUND to TRUE |
| 116 | + # if all listed variables are TRUE |
| 117 | + find_package_handle_standard_args(GPERFTOOLS |
| 118 | + FOUND_VAR GPERFTOOLS_FOUND |
| 119 | + REQUIRED_VARS GPERFTOOLS_LIBRARIES GPERFTOOLS_INCLUDE_DIRS |
| 120 | + HANDLE_COMPONENTS) |
| 121 | + |
| 122 | + mark_as_advanced(GPERFTOOLS_INCLUDE_DIR GPERFTOOLS_LIBRARY |
| 123 | + GPERFTOOLS_INCLUDE_DIRS GPERFTOOLS_LIBRARIES) |
| 124 | + |
| 125 | + # Add linker flags that instruct the compiler to exclude built in memory |
| 126 | + # allocation functions. This works for GNU, Intel, and Clang. Other compilers |
| 127 | + # may need to be added in the future. |
| 128 | + if(GPERFTOOLS_LIBRARIES MATCHES "tcmalloc") |
| 129 | + if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR |
| 130 | + (CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") OR |
| 131 | + (CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR |
| 132 | + ((CMAKE_CXX_COMPILER_ID MATCHES "Intel") AND (NOT CMAKE_CXX_PLATFORM_ID MATCHES "Windows"))) |
| 133 | + list(APPEND GPERFTOOLS_LIBRARIES "-fno-builtin-malloc" |
| 134 | + "-fno-builtin-calloc" "-fno-builtin-realloc" "-fno-builtin-free") |
| 135 | + endif() |
| 136 | + endif() |
| 137 | + |
| 138 | + # Add libunwind flags to gperftools if the profiler is being used |
| 139 | + if(GPERFTOOLS_LIBRARIES MATCHES "profiler" AND LIBUNWIND_FOUND) |
| 140 | + list(APPEND GPERFTOOLS_INCLUDE_DIRS "${LIBUNWIND_INCLUDE_DIRS}") |
| 141 | + list(APPEND GPERFTOOLS_LIBRARIES "${LIBUNWIND_LIBRARIES}") |
| 142 | + endif() |
| 143 | + |
| 144 | + unset(GPERFTOOLS_DISABLE_PROFILER) |
| 145 | + |
| 146 | +endif() |
0 commit comments