BackwardConfig.cmake 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #
  2. # BackwardMacros.cmake
  3. # Copyright 2013 Google Inc. All Rights Reserved.
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a copy
  6. # of this software and associated documentation files (the "Software"), to deal
  7. # in the Software without restriction, including without limitation the rights
  8. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. # copies of the Software, and to permit persons to whom the Software is
  10. # furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. # SOFTWARE.
  22. ###############################################################################
  23. # OPTIONS
  24. ###############################################################################
  25. set(STACK_WALKING_UNWIND TRUE CACHE BOOL
  26. "Use compiler's unwind API")
  27. set(STACK_WALKING_BACKTRACE FALSE CACHE BOOL
  28. "Use backtrace from (e)glibc for stack walking")
  29. set(STACK_WALKING_LIBUNWIND FALSE CACHE BOOL
  30. "Use libunwind for stack walking")
  31. set(STACK_DETAILS_AUTO_DETECT TRUE CACHE BOOL
  32. "Auto detect backward's stack details dependencies")
  33. set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE CACHE BOOL
  34. "Use backtrace from (e)glibc for symbols resolution")
  35. set(STACK_DETAILS_DW FALSE CACHE BOOL
  36. "Use libdw to read debug info")
  37. set(STACK_DETAILS_BFD FALSE CACHE BOOL
  38. "Use libbfd to read debug info")
  39. set(STACK_DETAILS_DWARF FALSE CACHE BOOL
  40. "Use libdwarf/libelf to read debug info")
  41. if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT DEFINED BACKWARD_TESTS)
  42. # If this is a top level CMake project, we most lixely want the tests
  43. set(BACKWARD_TESTS ON CACHE BOOL "Enable tests")
  44. else()
  45. set(BACKWARD_TESTS OFF CACHE BOOL "Enable tests")
  46. endif()
  47. ###############################################################################
  48. # CONFIGS
  49. ###############################################################################
  50. include(FindPackageHandleStandardArgs)
  51. if (STACK_WALKING_LIBUNWIND)
  52. # libunwind works on the macOS without having to add special include
  53. # paths or libraries
  54. if (NOT APPLE)
  55. find_path(LIBUNWIND_INCLUDE_DIR NAMES "libunwind.h")
  56. find_library(LIBUNWIND_LIBRARY unwind)
  57. if (LIBUNWIND_LIBRARY)
  58. include(CheckSymbolExists)
  59. check_symbol_exists(UNW_INIT_SIGNAL_FRAME libunwind.h HAVE_UNW_INIT_SIGNAL_FRAME)
  60. if (NOT HAVE_UNW_INIT_SIGNAL_FRAME)
  61. message(STATUS "libunwind does not support unwinding from signal handler frames")
  62. endif()
  63. endif()
  64. set(LIBUNWIND_INCLUDE_DIRS ${LIBUNWIND_INCLUDE_DIR})
  65. set(LIBDWARF_LIBRARIES ${LIBUNWIND_LIBRARY})
  66. find_package_handle_standard_args(libunwind DEFAULT_MSG
  67. LIBUNWIND_LIBRARY LIBUNWIND_INCLUDE_DIR)
  68. mark_as_advanced(LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARY)
  69. list(APPEND _BACKWARD_LIBRARIES ${LIBUNWIND_LIBRARY})
  70. endif()
  71. # Disable other unwinders if libunwind is found
  72. set(STACK_WALKING_UNWIND FALSE)
  73. set(STACK_WALKING_BACKTRACE FALSE)
  74. endif()
  75. if (${STACK_DETAILS_AUTO_DETECT})
  76. # find libdw
  77. find_path(LIBDW_INCLUDE_DIR NAMES "elfutils/libdw.h" "elfutils/libdwfl.h")
  78. find_library(LIBDW_LIBRARY dw)
  79. set(LIBDW_INCLUDE_DIRS ${LIBDW_INCLUDE_DIR} )
  80. set(LIBDW_LIBRARIES ${LIBDW_LIBRARY} )
  81. find_package_handle_standard_args(libdw DEFAULT_MSG
  82. LIBDW_LIBRARY LIBDW_INCLUDE_DIR)
  83. mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARY)
  84. # find libbfd
  85. find_path(LIBBFD_INCLUDE_DIR NAMES "bfd.h")
  86. find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h")
  87. find_library(LIBBFD_LIBRARY bfd)
  88. find_library(LIBDL_LIBRARY dl)
  89. set(LIBBFD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR})
  90. set(LIBBFD_LIBRARIES ${LIBBFD_LIBRARY} ${LIBDL_LIBRARY})
  91. find_package_handle_standard_args(libbfd DEFAULT_MSG
  92. LIBBFD_LIBRARY LIBBFD_INCLUDE_DIR
  93. LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
  94. mark_as_advanced(LIBBFD_INCLUDE_DIR LIBBFD_LIBRARY
  95. LIBDL_INCLUDE_DIR LIBDL_LIBRARY)
  96. # find libdwarf
  97. find_path(LIBDWARF_INCLUDE_DIR NAMES "libdwarf.h" PATH_SUFFIXES libdwarf)
  98. find_path(LIBELF_INCLUDE_DIR NAMES "libelf.h")
  99. find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h")
  100. find_library(LIBDWARF_LIBRARY dwarf)
  101. find_library(LIBELF_LIBRARY elf)
  102. find_library(LIBDL_LIBRARY dl)
  103. set(LIBDWARF_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIR} ${LIBELF_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR})
  104. set(LIBDWARF_LIBRARIES ${LIBDWARF_LIBRARY} ${LIBELF_LIBRARY} ${LIBDL_LIBRARY})
  105. find_package_handle_standard_args(libdwarf DEFAULT_MSG
  106. LIBDWARF_LIBRARY LIBDWARF_INCLUDE_DIR
  107. LIBELF_LIBRARY LIBELF_INCLUDE_DIR
  108. LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
  109. mark_as_advanced(LIBDWARF_INCLUDE_DIR LIBDWARF_LIBRARY
  110. LIBELF_INCLUDE_DIR LIBELF_LIBRARY
  111. LIBDL_INCLUDE_DIR LIBDL_LIBRARY)
  112. if (LIBDW_FOUND)
  113. LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDW_INCLUDE_DIRS})
  114. LIST(APPEND _BACKWARD_LIBRARIES ${LIBDW_LIBRARIES})
  115. set(STACK_DETAILS_DW TRUE)
  116. set(STACK_DETAILS_BFD FALSE)
  117. set(STACK_DETAILS_DWARF FALSE)
  118. set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
  119. elseif(LIBBFD_FOUND)
  120. LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIRS})
  121. LIST(APPEND _BACKWARD_LIBRARIES ${LIBBFD_LIBRARIES})
  122. # If we attempt to link against static bfd, make sure to link its dependencies, too
  123. get_filename_component(bfd_lib_ext "${LIBBFD_LIBRARY}" EXT)
  124. if (bfd_lib_ext STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}")
  125. list(APPEND _BACKWARD_LIBRARIES iberty z)
  126. endif()
  127. set(STACK_DETAILS_DW FALSE)
  128. set(STACK_DETAILS_BFD TRUE)
  129. set(STACK_DETAILS_DWARF FALSE)
  130. set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
  131. elseif(LIBDWARF_FOUND)
  132. LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIRS})
  133. LIST(APPEND _BACKWARD_LIBRARIES ${LIBDWARF_LIBRARIES})
  134. set(STACK_DETAILS_DW FALSE)
  135. set(STACK_DETAILS_BFD FALSE)
  136. set(STACK_DETAILS_DWARF TRUE)
  137. set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
  138. else()
  139. set(STACK_DETAILS_DW FALSE)
  140. set(STACK_DETAILS_BFD FALSE)
  141. set(STACK_DETAILS_DWARF FALSE)
  142. set(STACK_DETAILS_BACKTRACE_SYMBOL TRUE)
  143. endif()
  144. else()
  145. if (STACK_DETAILS_DW)
  146. LIST(APPEND _BACKWARD_LIBRARIES dw)
  147. endif()
  148. if (STACK_DETAILS_BFD)
  149. LIST(APPEND _BACKWARD_LIBRARIES bfd dl)
  150. endif()
  151. if (STACK_DETAILS_DWARF)
  152. LIST(APPEND _BACKWARD_LIBRARIES dwarf elf)
  153. endif()
  154. endif()
  155. macro(map_definitions var_prefix define_prefix)
  156. foreach(def ${ARGN})
  157. if (${${var_prefix}${def}})
  158. LIST(APPEND _BACKWARD_DEFINITIONS "${define_prefix}${def}=1")
  159. else()
  160. LIST(APPEND _BACKWARD_DEFINITIONS "${define_prefix}${def}=0")
  161. endif()
  162. endforeach()
  163. endmacro()
  164. if (NOT _BACKWARD_DEFINITIONS)
  165. map_definitions("STACK_WALKING_" "BACKWARD_HAS_" UNWIND LIBUNWIND BACKTRACE)
  166. map_definitions("STACK_DETAILS_" "BACKWARD_HAS_" BACKTRACE_SYMBOL DW BFD DWARF)
  167. endif()
  168. set(BACKWARD_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}")
  169. set(BACKWARD_HAS_EXTERNAL_LIBRARIES FALSE)
  170. set(FIND_PACKAGE_REQUIRED_VARS BACKWARD_INCLUDE_DIR)
  171. if(DEFINED _BACKWARD_LIBRARIES)
  172. set(BACKWARD_HAS_EXTERNAL_LIBRARIES TRUE)
  173. list(APPEND FIND_PACKAGE_REQUIRED_VARS _BACKWARD_LIBRARIES)
  174. endif()
  175. include(FindPackageHandleStandardArgs)
  176. find_package_handle_standard_args(Backward
  177. REQUIRED_VARS ${FIND_PACKAGE_REQUIRED_VARS}
  178. )
  179. list(APPEND _BACKWARD_INCLUDE_DIRS ${BACKWARD_INCLUDE_DIR})
  180. set(BACKWARD_INCLUDE_DIRS ${_BACKWARD_INCLUDE_DIRS} CACHE INTERNAL "_BACKWARD_INCLUDE_DIRS")
  181. set(BACKWARD_DEFINITIONS ${_BACKWARD_DEFINITIONS} CACHE INTERNAL "BACKWARD_DEFINITIONS")
  182. set(BACKWARD_LIBRARIES ${_BACKWARD_LIBRARIES} CACHE INTERNAL "BACKWARD_LIBRARIES")
  183. mark_as_advanced(BACKWARD_INCLUDE_DIRS BACKWARD_DEFINITIONS BACKWARD_LIBRARIES)
  184. # Expand each definition in BACKWARD_DEFINITIONS to its own cmake var and export
  185. # to outer scope
  186. foreach(var ${BACKWARD_DEFINITIONS})
  187. string(REPLACE "=" ";" var_as_list ${var})
  188. list(GET var_as_list 0 var_name)
  189. list(GET var_as_list 1 var_value)
  190. set(${var_name} ${var_value})
  191. mark_as_advanced(${var_name})
  192. endforeach()