File: FindBackward.cmake

package info (click to toggle)
jazz2-native 3.3.0-1
  • links: PTS, VCS
  • area: contrib
  • in suites:
  • size: 16,008 kB
  • sloc: cpp: 162,929; xml: 111; python: 31; makefile: 5; sh: 2
file content (227 lines) | stat: -rw-r--r-- 9,228 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#
# FindBackward.cmake
# Copyright 2013-2024 Google Inc. All Rights Reserved.
# Copyright © 2024 Dan R.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#

include(ncine_helpers)
include(FindPackageHandleStandardArgs)
include(CMakeDependentOption)

cmake_dependent_option(STACK_DETAILS_AUTO_DETECT "Auto detect Backward's stack details dependencies" ON "NOT WIN32" OFF)

set(STACK_WALKING_UNWIND ON CACHE BOOL "Use compiler's unwind API")
set(STACK_WALKING_BACKTRACE OFF CACHE BOOL "Use backtrace from (e)glibc for stack walking")
set(STACK_WALKING_LIBUNWIND OFF CACHE BOOL "Use libunwind for stack walking")

set(STACK_DETAILS_BACKTRACE_SYMBOL OFF CACHE BOOL "Use backtrace from (e)glibc for symbols resolution")
set(STACK_DETAILS_DW OFF CACHE BOOL "Use libdw to read debug info")
set(STACK_DETAILS_BFD OFF CACHE BOOL "Use libbfd to read debug info")
set(STACK_DETAILS_DWARF OFF CACHE BOOL "Use libdwarf/libelf to read debug info")

if(STACK_WALKING_LIBUNWIND)
	# libunwind works on the macOS without having to add special include paths or libraries
	if(NOT APPLE)
		find_path(LIBUNWIND_INCLUDE_DIR NAMES "libunwind.h")
		find_library(LIBUNWIND_LIBRARY unwind)

		if(LIBUNWIND_LIBRARY)
			include(CheckSymbolExists)
			check_symbol_exists(UNW_INIT_SIGNAL_FRAME libunwind.h HAVE_UNW_INIT_SIGNAL_FRAME)
			if(NOT HAVE_UNW_INIT_SIGNAL_FRAME)
				message(STATUS "libunwind does not support unwinding from signal handler frames")
			endif()
		endif()

		set(LIBUNWIND_INCLUDE_DIRS ${LIBUNWIND_INCLUDE_DIR})
		set(LIBDWARF_LIBRARIES ${LIBUNWIND_LIBRARY})
		find_package_handle_standard_args(libunwind DEFAULT_MSG LIBUNWIND_LIBRARY LIBUNWIND_INCLUDE_DIR)
		mark_as_advanced(LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARY)
		list(APPEND _BACKWARD_LIBRARIES ${LIBUNWIND_LIBRARY})
	endif()

	# Disable other unwinders if libunwind is found
	set(STACK_WALKING_UNWIND OFF)
	set(STACK_WALKING_BACKTRACE OFF)
endif()

if(${STACK_DETAILS_AUTO_DETECT})
	if(NOT CMAKE_VERSION VERSION_LESS 3.17)
		set(_name_mismatched_arg NAME_MISMATCHED)
	endif()
	# Find libdw
	find_path(LIBDW_INCLUDE_DIR NAMES "elfutils/libdw.h" "elfutils/libdwfl.h")
	find_library(LIBDW_LIBRARY dw)
	# In case it's statically linked, look for all the possible dependencies
	find_library(LIBELF_LIBRARY elf)
	find_library(LIBPTHREAD_LIBRARY pthread)
	find_library(LIBZ_LIBRARY z)
	find_library(LIBBZ2_LIBRARY bz2)
	find_library(LIBLZMA_LIBRARY lzma)
	find_library(LIBZSTD_LIBRARY zstd)
	set(LIBDW_INCLUDE_DIRS ${LIBDW_INCLUDE_DIR})
	set(LIBDW_LIBRARIES ${LIBDW_LIBRARY}
		$<$<BOOL:${LIBELF_LIBRARY}>:${LIBELF_LIBRARY}>
		$<$<BOOL:${LIBPTHREAD_LIBRARY}>:${LIBPTHREAD_LIBRARY}>
		$<$<BOOL:${LIBZ_LIBRARY}>:${LIBZ_LIBRARY}>
		$<$<BOOL:${LIBBZ2_LIBRARY}>:${LIBBZ2_LIBRARY}>
		$<$<BOOL:${LIBLZMA_LIBRARY}>:${LIBLZMA_LIBRARY}>
		$<$<BOOL:${LIBZSTD_LIBRARY}>:${LIBZSTD_LIBRARY}>)
	find_package_handle_standard_args(libdw ${_name_mismatched_arg} REQUIRED_VARS LIBDW_LIBRARY LIBDW_INCLUDE_DIR)
	mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARY)

	# Find libbfd
	find_path(LIBBFD_INCLUDE_DIR NAMES "bfd.h")
	find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h")
	find_library(LIBBFD_LIBRARY bfd)
	find_library(LIBDL_LIBRARY dl)
	set(LIBBFD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR})
	set(LIBBFD_LIBRARIES ${LIBBFD_LIBRARY} ${LIBDL_LIBRARY})
	find_package_handle_standard_args(libbfd ${_name_mismatched_arg} REQUIRED_VARS LIBBFD_LIBRARY LIBBFD_INCLUDE_DIR
		LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
	mark_as_advanced(LIBBFD_INCLUDE_DIR LIBBFD_LIBRARY LIBDL_INCLUDE_DIR LIBDL_LIBRARY)

	# Find libdwarf
	find_path(LIBDWARF_INCLUDE_DIR NAMES "libdwarf.h" PATH_SUFFIXES libdwarf)
	find_path(LIBELF_INCLUDE_DIR NAMES "libelf.h")
	find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h")
	find_library(LIBDWARF_LIBRARY dwarf)
	find_library(LIBELF_LIBRARY elf)
	find_library(LIBDL_LIBRARY dl)
	set(LIBDWARF_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIR} ${LIBELF_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR})
	set(LIBDWARF_LIBRARIES ${LIBDWARF_LIBRARY} ${LIBELF_LIBRARY} ${LIBDL_LIBRARY})
	find_package_handle_standard_args(libdwarf ${_name_mismatched_arg} REQUIRED_VARS LIBDWARF_LIBRARY LIBDWARF_INCLUDE_DIR
		LIBELF_LIBRARY LIBELF_INCLUDE_DIR LIBDL_LIBRARY LIBDL_INCLUDE_DIR)
	mark_as_advanced(LIBDWARF_INCLUDE_DIR LIBDWARF_LIBRARY LIBELF_INCLUDE_DIR LIBELF_LIBRARY LIBDL_INCLUDE_DIR LIBDL_LIBRARY)

	if(LIBDW_FOUND)
		LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDW_INCLUDE_DIRS})
		LIST(APPEND _BACKWARD_LIBRARIES ${LIBDW_LIBRARIES})
		set(STACK_DETAILS_DW ON)
		set(STACK_DETAILS_BFD OFF)
		set(STACK_DETAILS_DWARF OFF)
		set(STACK_DETAILS_BACKTRACE_SYMBOL OFF)
		message(STATUS "Backward will use libdw to read stack traces")
	elseif(LIBBFD_FOUND)
		LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIRS})
		LIST(APPEND _BACKWARD_LIBRARIES ${LIBBFD_LIBRARIES})

		# If we attempt to link against static bfd, make sure to link its dependencies too
		get_filename_component(bfd_lib_ext "${LIBBFD_LIBRARY}" EXT)
		if(bfd_lib_ext STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}")
			find_library(LIBSFRAME_LIBRARY NAMES sframe)
			if(LIBSFRAME_LIBRARY)
				list(APPEND _BACKWARD_LIBRARIES ${LIBSFRAME_LIBRARY})
			endif()

			list(APPEND _BACKWARD_LIBRARIES iberty z)
			message(STATUS "Backward will use libbfd (static) to read stack traces")
		else()
			message(STATUS "Backward will use libbfd to read stack traces")
		endif()

		set(STACK_DETAILS_DW OFF)
		set(STACK_DETAILS_BFD ON)
		set(STACK_DETAILS_DWARF OFF)
		set(STACK_DETAILS_BACKTRACE_SYMBOL OFF)
	elseif(LIBDWARF_FOUND)
		LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIRS})
		LIST(APPEND _BACKWARD_LIBRARIES ${LIBDWARF_LIBRARIES})

		set(STACK_DETAILS_DW OFF)
		set(STACK_DETAILS_BFD OFF)
		set(STACK_DETAILS_DWARF ON)
		set(STACK_DETAILS_BACKTRACE_SYMBOL OFF)
		message(STATUS "Backward will use libdwarf to read stack traces")
	else()
		set(STACK_DETAILS_DW OFF)
		set(STACK_DETAILS_BFD OFF)
		set(STACK_DETAILS_DWARF OFF)
		set(STACK_DETAILS_BACKTRACE_SYMBOL ON)
	endif()
else()
	if(STACK_DETAILS_DW)
		LIST(APPEND _BACKWARD_LIBRARIES dw)
	endif()

	if(STACK_DETAILS_BFD)
		LIST(APPEND _BACKWARD_LIBRARIES bfd dl)
	endif()

	if(STACK_DETAILS_DWARF)
		LIST(APPEND _BACKWARD_LIBRARIES dwarf elf)
	endif()
endif()

macro(map_definitions var_prefix define_prefix)
	foreach(def ${ARGN})
		if(${${var_prefix}${def}})
			LIST(APPEND _BACKWARD_DEFINITIONS "${define_prefix}${def}")
		endif()
	endforeach()
endmacro()

if(NOT _BACKWARD_DEFINITIONS)
	map_definitions("STACK_WALKING_" "BACKWARD_HAS_" UNWIND LIBUNWIND BACKTRACE)
	map_definitions("STACK_DETAILS_" "BACKWARD_HAS_" BACKTRACE_SYMBOL DW BFD DWARF)
endif()

if(WIN32)
	list(APPEND _BACKWARD_LIBRARIES dbghelp psapi)
	if(MINGW)
		include(CheckCXXCompilerFlag)
		check_cxx_compiler_flag(-gcodeview SUPPORT_WINDOWS_DEBUG_INFO)	
		if(SUPPORT_WINDOWS_DEBUG_INFO)
			set(CMAKE_EXE_LINKER_FLAGS "-Wl,--pdb=")
			add_compile_options(-gcodeview)
		else()
			set(MINGW_MSVCR_LIBRARY "msvcr90$<$<CONFIG:DEBUG>:d>" CACHE STRING "MinGW MSVC runtime import library")
			list(APPEND _BACKWARD_LIBRARIES ${MINGW_MSVCR_LIBRARY})
		endif()
	endif()	
endif()

#list(APPEND _BACKWARD_INCLUDE_DIRS ${BACKWARD_INCLUDE_DIR})
#list(APPEND _BACKWARD_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
list(APPEND _BACKWARD_INCLUDE_DIRS "${NCINE_SOURCE_DIR}/Shared")

set(BACKWARD_INCLUDE_DIRS ${_BACKWARD_INCLUDE_DIRS} CACHE INTERNAL "BACKWARD_INCLUDE_DIRS")
set(BACKWARD_DEFINITIONS ${_BACKWARD_DEFINITIONS} CACHE INTERNAL "BACKWARD_DEFINITIONS")
set(BACKWARD_LIBRARIES ${_BACKWARD_LIBRARIES} CACHE INTERNAL "BACKWARD_LIBRARIES")
mark_as_advanced(BACKWARD_INCLUDE_DIRS BACKWARD_DEFINITIONS BACKWARD_LIBRARIES)

# Expand each definition in BACKWARD_DEFINITIONS to its own cmake var and export to outer scope
foreach(var ${BACKWARD_DEFINITIONS})
	set(${var} ON)
	mark_as_advanced(${var})
endforeach()

ncine_add_dependency(Backward INTERFACE)

target_sources(Backward PUBLIC "${NCINE_SOURCE_DIR}/Shared/Core/Backward.h")

source_group("Header Files" FILES "${NCINE_SOURCE_DIR}/Shared/Core/Backward.h")

target_compile_definitions(Backward INTERFACE ${BACKWARD_DEFINITIONS})
target_include_directories(Backward INTERFACE ${BACKWARD_INCLUDE_DIRS})
if(BACKWARD_LIBRARIES)
	target_link_libraries(Backward INTERFACE ${BACKWARD_LIBRARIES})
endif()