You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BackwardConfig.cmake 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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. if(NOT CMAKE_VERSION VERSION_LESS 3.17)
  77. set(_name_mismatched_arg NAME_MISMATCHED)
  78. endif()
  79. # find libdw
  80. find_path(LIBDW_INCLUDE_DIR NAMES "elfutils/libdw.h" "elfutils/libdwfl.h")
  81. find_library(LIBDW_LIBRARY dw)
  82. set(LIBDW_INCLUDE_DIRS ${LIBDW_INCLUDE_DIR} )
  83. set(LIBDW_LIBRARIES ${LIBDW_LIBRARY} )
  84. find_package_handle_standard_args(libdw ${_name_mismatched_arg}
  85. REQUIRED_VARS LIBDW_LIBRARY LIBDW_INCLUDE_DIR)
  86. mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARY)
  87. # find libbfd
  88. find_path(LIBBFD_INCLUDE_DIR NAMES "bfd.h")
  89. find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h")
  90. find_library(LIBBFD_LIBRARY bfd)
  91. find_library(LIBDL_LIBRARY dl)
  92. set(LIBBFD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR})
  93. set(LIBBFD_LIBRARIES ${LIBBFD_LIBRARY} ${LIBDL_LIBRARY})
  94. find_package_handle_standard_args(libbfd ${_name_mismatched_arg}
  95. REQUIRED_VARS LIBBFD_LIBRARY LIBBFD_INCLUDE_DIR
  96. LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
  97. mark_as_advanced(LIBBFD_INCLUDE_DIR LIBBFD_LIBRARY
  98. LIBDL_INCLUDE_DIR LIBDL_LIBRARY)
  99. # find libdwarf
  100. find_path(LIBDWARF_INCLUDE_DIR NAMES "libdwarf.h" PATH_SUFFIXES libdwarf)
  101. find_path(LIBELF_INCLUDE_DIR NAMES "libelf.h")
  102. find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h")
  103. find_library(LIBDWARF_LIBRARY dwarf)
  104. find_library(LIBELF_LIBRARY elf)
  105. find_library(LIBDL_LIBRARY dl)
  106. set(LIBDWARF_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIR} ${LIBELF_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR})
  107. set(LIBDWARF_LIBRARIES ${LIBDWARF_LIBRARY} ${LIBELF_LIBRARY} ${LIBDL_LIBRARY})
  108. find_package_handle_standard_args(libdwarf ${_name_mismatched_arg}
  109. REQUIRED_VARS LIBDWARF_LIBRARY LIBDWARF_INCLUDE_DIR
  110. LIBELF_LIBRARY LIBELF_INCLUDE_DIR
  111. LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
  112. mark_as_advanced(LIBDWARF_INCLUDE_DIR LIBDWARF_LIBRARY
  113. LIBELF_INCLUDE_DIR LIBELF_LIBRARY
  114. LIBDL_INCLUDE_DIR LIBDL_LIBRARY)
  115. if (LIBDW_FOUND)
  116. LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDW_INCLUDE_DIRS})
  117. LIST(APPEND _BACKWARD_LIBRARIES ${LIBDW_LIBRARIES})
  118. set(STACK_DETAILS_DW TRUE)
  119. set(STACK_DETAILS_BFD FALSE)
  120. set(STACK_DETAILS_DWARF FALSE)
  121. set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
  122. elseif(LIBBFD_FOUND)
  123. LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIRS})
  124. LIST(APPEND _BACKWARD_LIBRARIES ${LIBBFD_LIBRARIES})
  125. # If we attempt to link against static bfd, make sure to link its dependencies, too
  126. get_filename_component(bfd_lib_ext "${LIBBFD_LIBRARY}" EXT)
  127. if (bfd_lib_ext STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}")
  128. if (NOT APPLE)
  129. list(APPEND _BACKWARD_LIBRARIES iberty z)
  130. endif()
  131. endif()
  132. set(STACK_DETAILS_DW FALSE)
  133. set(STACK_DETAILS_BFD TRUE)
  134. set(STACK_DETAILS_DWARF FALSE)
  135. set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
  136. elseif(LIBDWARF_FOUND)
  137. LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIRS})
  138. LIST(APPEND _BACKWARD_LIBRARIES ${LIBDWARF_LIBRARIES})
  139. set(STACK_DETAILS_DW FALSE)
  140. set(STACK_DETAILS_BFD FALSE)
  141. set(STACK_DETAILS_DWARF TRUE)
  142. set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE)
  143. else()
  144. set(STACK_DETAILS_DW FALSE)
  145. set(STACK_DETAILS_BFD FALSE)
  146. set(STACK_DETAILS_DWARF FALSE)
  147. set(STACK_DETAILS_BACKTRACE_SYMBOL TRUE)
  148. endif()
  149. else()
  150. if (STACK_DETAILS_DW)
  151. LIST(APPEND _BACKWARD_LIBRARIES dw)
  152. endif()
  153. if (STACK_DETAILS_BFD)
  154. LIST(APPEND _BACKWARD_LIBRARIES bfd dl)
  155. endif()
  156. if (STACK_DETAILS_DWARF)
  157. LIST(APPEND _BACKWARD_LIBRARIES dwarf elf)
  158. endif()
  159. endif()
  160. macro(map_definitions var_prefix define_prefix)
  161. foreach(def ${ARGN})
  162. if (${${var_prefix}${def}})
  163. LIST(APPEND _BACKWARD_DEFINITIONS "${define_prefix}${def}=1")
  164. else()
  165. LIST(APPEND _BACKWARD_DEFINITIONS "${define_prefix}${def}=0")
  166. endif()
  167. endforeach()
  168. endmacro()
  169. if (NOT _BACKWARD_DEFINITIONS)
  170. map_definitions("STACK_WALKING_" "BACKWARD_HAS_" UNWIND LIBUNWIND BACKTRACE)
  171. map_definitions("STACK_DETAILS_" "BACKWARD_HAS_" BACKTRACE_SYMBOL DW BFD DWARF)
  172. endif()
  173. if(WIN32)
  174. list(APPEND _BACKWARD_LIBRARIES dbghelp psapi)
  175. if(MINGW)
  176. set(MINGW_MSVCR_LIBRARY "msvcr90$<$<CONFIG:DEBUG>:d>" CACHE STRING "Mingw MSVC runtime import library")
  177. list(APPEND _BACKWARD_LIBRARIES ${MINGW_MSVCR_LIBRARY})
  178. endif()
  179. endif()
  180. set(BACKWARD_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}")
  181. set(BACKWARD_HAS_EXTERNAL_LIBRARIES FALSE)
  182. set(FIND_PACKAGE_REQUIRED_VARS BACKWARD_INCLUDE_DIR)
  183. if(DEFINED _BACKWARD_LIBRARIES)
  184. set(BACKWARD_HAS_EXTERNAL_LIBRARIES TRUE)
  185. list(APPEND FIND_PACKAGE_REQUIRED_VARS _BACKWARD_LIBRARIES)
  186. endif()
  187. include(FindPackageHandleStandardArgs)
  188. find_package_handle_standard_args(Backward
  189. REQUIRED_VARS ${FIND_PACKAGE_REQUIRED_VARS}
  190. )
  191. list(APPEND _BACKWARD_INCLUDE_DIRS ${BACKWARD_INCLUDE_DIR})
  192. macro(add_backward target)
  193. target_include_directories(${target} PRIVATE ${BACKWARD_INCLUDE_DIRS})
  194. set_property(TARGET ${target} APPEND PROPERTY COMPILE_DEFINITIONS ${BACKWARD_DEFINITIONS})
  195. set_property(TARGET ${target} APPEND PROPERTY LINK_LIBRARIES ${BACKWARD_LIBRARIES})
  196. endmacro()
  197. set(BACKWARD_INCLUDE_DIRS ${_BACKWARD_INCLUDE_DIRS} CACHE INTERNAL "_BACKWARD_INCLUDE_DIRS")
  198. set(BACKWARD_DEFINITIONS ${_BACKWARD_DEFINITIONS} CACHE INTERNAL "BACKWARD_DEFINITIONS")
  199. set(BACKWARD_LIBRARIES ${_BACKWARD_LIBRARIES} CACHE INTERNAL "BACKWARD_LIBRARIES")
  200. mark_as_advanced(BACKWARD_INCLUDE_DIRS BACKWARD_DEFINITIONS BACKWARD_LIBRARIES)
  201. # Expand each definition in BACKWARD_DEFINITIONS to its own cmake var and export
  202. # to outer scope
  203. foreach(var ${BACKWARD_DEFINITIONS})
  204. string(REPLACE "=" ";" var_as_list ${var})
  205. list(GET var_as_list 0 var_name)
  206. list(GET var_as_list 1 var_value)
  207. set(${var_name} ${var_value})
  208. mark_as_advanced(${var_name})
  209. endforeach()
  210. if (NOT TARGET Backward::Backward)
  211. add_library(Backward::Backward INTERFACE IMPORTED)
  212. set_target_properties(Backward::Backward PROPERTIES
  213. INTERFACE_INCLUDE_DIRECTORIES "${BACKWARD_INCLUDE_DIRS}"
  214. INTERFACE_COMPILE_DEFINITIONS "${BACKWARD_DEFINITIONS}"
  215. )
  216. if(BACKWARD_HAS_EXTERNAL_LIBRARIES)
  217. set_target_properties(Backward::Backward PROPERTIES
  218. INTERFACE_LINK_LIBRARIES "${BACKWARD_LIBRARIES}"
  219. )
  220. endif()
  221. endif()