CMake improvements (#57)
This commit is contained in:
parent
e14eac364f
commit
98368fb417
303
CMakeLists.txt
303
CMakeLists.txt
@ -1,15 +1,24 @@
|
|||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
if(${CMAKE_VERSION} VERSION_LESS 3.12)
|
include(cmake/PreventInSourceBuilds.cmake)
|
||||||
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
|
||||||
endif()
|
# ---- Initialize Project ----
|
||||||
|
|
||||||
|
# Used to support find_package
|
||||||
|
set(package_name "cpptrace")
|
||||||
|
|
||||||
project(
|
project(
|
||||||
cpptrace
|
cpptrace
|
||||||
VERSION 0.2.1
|
VERSION 0.2.1
|
||||||
|
DESCRIPTION "Simple, portable, and self-contained stacktrace library for C++11 and newer "
|
||||||
|
HOMEPAGE_URL "https://github.com/jeremy-rifkin/cpptrace"
|
||||||
LANGUAGES C CXX
|
LANGUAGES C CXX
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Don't change include order, OptionVariables checks if project is top level
|
||||||
|
include(cmake/ProjectIsTopLevel.cmake)
|
||||||
|
include(cmake/OptionVariables.cmake)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
include(CheckCXXSourceCompiles)
|
include(CheckCXXSourceCompiles)
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
@ -22,47 +31,6 @@ if(CMAKE_GENERATOR STREQUAL "Ninja")
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(CPPTRACE_STATIC "" OFF)
|
|
||||||
|
|
||||||
option(CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE "" OFF)
|
|
||||||
option(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF "" OFF)
|
|
||||||
option(CPPTRACE_GET_SYMBOLS_WITH_LIBDL "" OFF)
|
|
||||||
option(CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE "" OFF)
|
|
||||||
option(CPPTRACE_GET_SYMBOLS_WITH_DBGHELP "" OFF)
|
|
||||||
option(CPPTRACE_GET_SYMBOLS_WITH_NOTHING "" OFF)
|
|
||||||
|
|
||||||
option(CPPTRACE_UNWIND_WITH_UNWIND "" OFF)
|
|
||||||
option(CPPTRACE_UNWIND_WITH_EXECINFO "" OFF)
|
|
||||||
option(CPPTRACE_UNWIND_WITH_WINAPI "" OFF)
|
|
||||||
option(CPPTRACE_UNWIND_WITH_DBGHELP "" OFF)
|
|
||||||
option(CPPTRACE_UNWIND_WITH_NOTHING "" OFF)
|
|
||||||
|
|
||||||
option(CPPTRACE_DEMANGLE_WITH_CXXABI "" OFF)
|
|
||||||
option(CPPTRACE_DEMANGLE_WITH_WINAPI "" OFF)
|
|
||||||
option(CPPTRACE_DEMANGLE_WITH_NOTHING "" OFF)
|
|
||||||
|
|
||||||
set(CPPTRACE_BACKTRACE_PATH "" CACHE STRING "Path to backtrace.h, if the compiler doesn't already know it. Check /usr/lib/gcc/x86_64-linux-gnu/*/include.")
|
|
||||||
set(CPPTRACE_HARD_MAX_FRAMES "" CACHE STRING "Hard limit on unwinding depth. Default is 100.")
|
|
||||||
set(CPPTRACE_ADDR2LINE_PATH "" CACHE STRING "Absolute path to the addr2line executable you want to use.")
|
|
||||||
option(CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH "" OFF)
|
|
||||||
|
|
||||||
option(CPPTRACE_BUILD_TEST "" OFF)
|
|
||||||
option(CPPTRACE_BUILD_DEMO "" OFF)
|
|
||||||
option(CPPTRACE_BUILD_TEST_RDYNAMIC "" OFF)
|
|
||||||
|
|
||||||
option(CPPTRACE_USE_SYSTEM_LIBDWARF "" OFF)
|
|
||||||
option(CPPTRACE_SANITIZER_BUILD "" OFF)
|
|
||||||
|
|
||||||
mark_as_advanced(
|
|
||||||
CPPTRACE_BACKTRACE_PATH
|
|
||||||
CPPTRACE_ADDR2LINE_PATH
|
|
||||||
CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH
|
|
||||||
CPPTRACE_BUILD_TEST
|
|
||||||
CPPTRACE_BUILD_DEMO
|
|
||||||
CPPTRACE_BUILD_TEST_RDYNAMIC
|
|
||||||
CPPTRACE_SANITIZER_BUILD
|
|
||||||
)
|
|
||||||
|
|
||||||
if(CPPTRACE_SANITIZER_BUILD)
|
if(CPPTRACE_SANITIZER_BUILD)
|
||||||
add_compile_options(-fsanitize=address)
|
add_compile_options(-fsanitize=address)
|
||||||
add_link_options(-fsanitize=address)
|
add_link_options(-fsanitize=address)
|
||||||
@ -82,6 +50,7 @@ else()
|
|||||||
set(CPPTRACE_BACKTRACE_PATH_DEFINITION "")
|
set(CPPTRACE_BACKTRACE_PATH_DEFINITION "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# =============================================== Platform Support ===============================================
|
||||||
function(check_support var source includes libraries definitions)
|
function(check_support var source includes libraries definitions)
|
||||||
set(CMAKE_REQUIRED_INCLUDES "${includes}")
|
set(CMAKE_REQUIRED_INCLUDES "${includes}")
|
||||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
list(APPEND CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
@ -195,10 +164,25 @@ endif()
|
|||||||
|
|
||||||
# =============================================== Now define the library ===============================================
|
# =============================================== Now define the library ===============================================
|
||||||
|
|
||||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
# Target that we can modify (can't modify ALIAS targets)
|
||||||
|
# Target name should not be the same as ${PROJECT_NAME}, causes add_subdirectory issues
|
||||||
|
set(target_name "cpptrace-lib")
|
||||||
|
add_library(${target_name} ${build_type})
|
||||||
|
|
||||||
set(
|
# Alias to cause error at configuration time instead of link time if target is missing
|
||||||
sources
|
add_library(cpptrace::cpptrace ALIAS ${target_name})
|
||||||
|
|
||||||
|
# Add /include files to target
|
||||||
|
# This is solely for IDE benefit, doesn't affect building
|
||||||
|
target_sources(
|
||||||
|
${target_name} PRIVATE
|
||||||
|
include/cpptrace/cpptrace.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# add /src files to target
|
||||||
|
target_sources(
|
||||||
|
${target_name} PRIVATE
|
||||||
|
# src
|
||||||
src/cpptrace.cpp
|
src/cpptrace.cpp
|
||||||
src/demangle/demangle_with_cxxabi.cpp
|
src/demangle/demangle_with_cxxabi.cpp
|
||||||
src/demangle/demangle_with_winapi.cpp
|
src/demangle/demangle_with_winapi.cpp
|
||||||
@ -217,71 +201,89 @@ set(
|
|||||||
src/unwind/unwind_with_dbghelp.cpp
|
src/unwind/unwind_with_dbghelp.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(CPPTRACE_STATIC)
|
|
||||||
add_library(cpptrace STATIC ${sources} include/cpptrace/cpptrace.hpp)
|
|
||||||
else()
|
|
||||||
add_library(cpptrace SHARED ${sources} include/cpptrace/cpptrace.hpp)
|
|
||||||
set_property(TARGET cpptrace PROPERTY POSITION_INDEPENDENT_CODE ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
cpptrace
|
${target_name}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpptrace/>
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpptrace/>
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO
|
# ---- Generate Build Info Headers ----
|
||||||
target_compile_features(cpptrace PRIVATE cxx_range_for cxx_constexpr cxx_nullptr cxx_static_assert)
|
|
||||||
|
|
||||||
set_target_properties(
|
# used in export header generated below
|
||||||
cpptrace
|
if(NOT CPPTRACE_BUILD_SHARED)
|
||||||
PROPERTIES
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_STATIC_DEFINE)
|
||||||
CXX_STANDARD_REQUIRED TRUE
|
endif()
|
||||||
CXX_EXTENSIONS OFF
|
|
||||||
|
# generate header file with export macros prefixed with BASE_NAME
|
||||||
|
include(GenerateExportHeader)
|
||||||
|
generate_export_header(
|
||||||
|
${target_name}
|
||||||
|
BASE_NAME cpptrace
|
||||||
|
EXPORT_FILE_NAME include/cpptrace/cpptrace_export.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(
|
# ---- Library Properties ----
|
||||||
cpptrace
|
|
||||||
PRIVATE
|
# Hide all symbols by default
|
||||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Werror=return-type -Wundef>
|
# Use SameMajorVersion versioning for shared library runtime linker lookup
|
||||||
$<$<CXX_COMPILER_ID:GNU>:-Wuseless-cast>
|
set_target_properties(
|
||||||
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX /permissive->
|
${target_name} PROPERTIES
|
||||||
|
CXX_VISIBILITY_PRESET hidden
|
||||||
|
VISIBILITY_INLINES_HIDDEN YES
|
||||||
|
VERSION "${PROJECT_VERSION}"
|
||||||
|
SOVERSION "${PROJECT_VERSION_MAJOR}"
|
||||||
|
EXPORT_NAME "cpptrace"
|
||||||
|
OUTPUT_NAME "cpptrace"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Header files generated by CMake
|
||||||
|
target_include_directories(
|
||||||
|
${target_name} SYSTEM PUBLIC
|
||||||
|
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Header files from /include
|
||||||
|
target_include_directories(
|
||||||
|
${target_name} ${warning_guard} PUBLIC
|
||||||
|
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Require C++11 support
|
||||||
|
target_compile_features(
|
||||||
|
${target_name}
|
||||||
|
PRIVATE cxx_std_11
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================== Apply options to build ===============================================
|
# =============================================== Apply options to build ===============================================
|
||||||
|
|
||||||
if(HAS_CXX_EXCEPTION_TYPE)
|
if(HAS_CXX_EXCEPTION_TYPE)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_HAS_CXX_EXCEPTION_TYPE)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_HAS_CXX_EXCEPTION_TYPE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(check_backtrace_error)
|
|
||||||
if(NOT HAS_BACKTRACE)
|
|
||||||
if(NOT "${CPPTRACE_BACKTRACE_PATH}" STREQUAL "")
|
|
||||||
message(WARNING "Cpptrace: CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE specified but libbacktrace doesn't appear installed or configured properly.")
|
|
||||||
else()
|
|
||||||
message(WARNING "Cpptrace: CPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE specified but libbacktrace doesn't appear installed or configured properly. You may need to specify CPPTRACE_BACKTRACE_PATH.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Symbols
|
# Symbols
|
||||||
if(CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE)
|
if(CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE)
|
||||||
check_backtrace_error()
|
if(NOT HAS_BACKTRACE)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE)
|
if(NOT "${CPPTRACE_BACKTRACE_PATH}" STREQUAL "")
|
||||||
target_link_libraries(cpptrace PRIVATE backtrace)
|
message(WARNING "Cpptrace: Using libbacktrace for symbols but libbacktrace doesn't appear installed or configured properly.")
|
||||||
|
else()
|
||||||
|
message(WARNING "Cpptrace: Using libbacktrace for symbols but libbacktrace doesn't appear installed or configured properly. You may need to specify CPPTRACE_BACKTRACE_PATH.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE)
|
||||||
|
target_link_libraries(${target_name} PRIVATE backtrace dl)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_GET_SYMBOLS_WITH_LIBDL)
|
if(CPPTRACE_GET_SYMBOLS_WITH_LIBDL)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_GET_SYMBOLS_WITH_LIBDL)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_GET_SYMBOLS_WITH_LIBDL)
|
||||||
target_link_libraries(cpptrace PRIVATE dl)
|
target_link_libraries(${target_name} PRIVATE dl)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE)
|
if(CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE)
|
||||||
# set(CPPTRACE_ADDR2LINE_PATH "" CACHE STRING "Absolute path to the addr2line executable you want to use.")
|
# set(CPPTRACE_ADDR2LINE_PATH "" CACHE STRING "Absolute path to the addr2line executable you want to use.")
|
||||||
# option(CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH "" OFF)
|
# option(CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH "" OFF)
|
||||||
if(CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH)
|
if(CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH)
|
||||||
else()
|
else()
|
||||||
if("${CPPTRACE_ADDR2LINE_PATH}" STREQUAL "")
|
if("${CPPTRACE_ADDR2LINE_PATH}" STREQUAL "")
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
@ -293,35 +295,46 @@ if(CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE)
|
|||||||
set(CPPTRACE_ADDR2LINE_PATH_FINAL "${CPPTRACE_ADDR2LINE_PATH}")
|
set(CPPTRACE_ADDR2LINE_PATH_FINAL "${CPPTRACE_ADDR2LINE_PATH}")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Cpptrace: Using ${CPPTRACE_ADDR2LINE_PATH_FINAL} for addr2line path")
|
message(STATUS "Cpptrace: Using ${CPPTRACE_ADDR2LINE_PATH_FINAL} for addr2line path")
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_ADDR2LINE_PATH="${CPPTRACE_ADDR2LINE_PATH_FINAL}")
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_ADDR2LINE_PATH="${CPPTRACE_ADDR2LINE_PATH_FINAL}")
|
||||||
endif()
|
endif()
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE)
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
target_link_libraries(cpptrace PRIVATE dl)
|
target_link_libraries(${target_name} PRIVATE dl)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF)
|
if(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF)
|
||||||
if(CPPTRACE_USE_SYSTEM_LIBDWARF)
|
if(CPPTRACE_USE_EXTERNAL_LIBDWARF)
|
||||||
find_package(libdwarf REQUIRED)
|
find_package(libdwarf REQUIRED)
|
||||||
target_link_libraries(cpptrace PRIVATE libdwarf)
|
target_link_libraries(${target_name} PRIVATE libdwarf::dwarf-static)
|
||||||
else()
|
else()
|
||||||
add_subdirectory(bundled/libdwarf)
|
add_subdirectory(bundled/libdwarf)
|
||||||
target_link_libraries(cpptrace PRIVATE dwarf)
|
target_link_libraries(${target_name} PRIVATE dwarf)
|
||||||
|
# set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||||
|
# set(PIC_ALWAYS TRUE)
|
||||||
|
# set(BUILD_DWARFDUMP FALSE)
|
||||||
|
# include(FetchContent)
|
||||||
|
# FetchContent_Declare(
|
||||||
|
# libdwarf
|
||||||
|
# GIT_REPOSITORY https://github.com/jeremy-rifkin/libdwarf-code.git
|
||||||
|
# GIT_TAG 4ca6a7bc86b27d56741923f03c15b5aa274efc28 # v0.8.0
|
||||||
|
# )
|
||||||
|
# FetchContent_MakeAvailable(libdwarf)
|
||||||
|
# target_link_libraries(${target_name} PRIVATE dwarf-static)
|
||||||
endif()
|
endif()
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
target_link_libraries(cpptrace PRIVATE dl)
|
target_link_libraries(${target_name} PRIVATE dl)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_GET_SYMBOLS_WITH_DBGHELP)
|
if(CPPTRACE_GET_SYMBOLS_WITH_DBGHELP)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_GET_SYMBOLS_WITH_DBGHELP)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_GET_SYMBOLS_WITH_DBGHELP)
|
||||||
target_link_libraries(cpptrace PRIVATE dbghelp)
|
target_link_libraries(${target_name} PRIVATE dbghelp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_GET_SYMBOLS_WITH_NOTHING)
|
if(CPPTRACE_GET_SYMBOLS_WITH_NOTHING)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_GET_SYMBOLS_WITH_NOTHING)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_GET_SYMBOLS_WITH_NOTHING)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Unwinding
|
# Unwinding
|
||||||
@ -329,30 +342,30 @@ if(CPPTRACE_UNWIND_WITH_UNWIND)
|
|||||||
if(NOT HAS_UNWIND)
|
if(NOT HAS_UNWIND)
|
||||||
message(WARNING "Cpptrace: CPPTRACE_UNWIND_WITH_UNWIND specified but libgcc unwind doesn't seem to be available.")
|
message(WARNING "Cpptrace: CPPTRACE_UNWIND_WITH_UNWIND specified but libgcc unwind doesn't seem to be available.")
|
||||||
endif()
|
endif()
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_UNWIND_WITH_UNWIND)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_UNWIND_WITH_UNWIND)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_UNWIND_WITH_EXECINFO)
|
if(CPPTRACE_UNWIND_WITH_EXECINFO)
|
||||||
if(NOT HAS_EXECINFO)
|
if(NOT HAS_EXECINFO)
|
||||||
message(WARNING "Cpptrace: CPPTRACE_UNWIND_WITH_EXECINFO specified but execinfo.h doesn't seem to be available.")
|
message(WARNING "Cpptrace: CPPTRACE_UNWIND_WITH_EXECINFO specified but execinfo.h doesn't seem to be available.")
|
||||||
endif()
|
endif()
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_UNWIND_WITH_EXECINFO)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_UNWIND_WITH_EXECINFO)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_UNWIND_WITH_WINAPI)
|
if(CPPTRACE_UNWIND_WITH_WINAPI)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_UNWIND_WITH_WINAPI)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_UNWIND_WITH_WINAPI)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_UNWIND_WITH_DBGHELP)
|
if(CPPTRACE_UNWIND_WITH_DBGHELP)
|
||||||
if(NOT HAS_STACKWALK)
|
if(NOT HAS_STACKWALK)
|
||||||
message(WARNING "Cpptrace: CPPTRACE_UNWIND_WITH_DBGHELP specified but dbghelp stackwalk64 doesn't seem to be available.")
|
message(WARNING "Cpptrace: CPPTRACE_UNWIND_WITH_DBGHELP specified but dbghelp stackwalk64 doesn't seem to be available.")
|
||||||
endif()
|
endif()
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_UNWIND_WITH_DBGHELP)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_UNWIND_WITH_DBGHELP)
|
||||||
target_link_libraries(cpptrace PRIVATE dbghelp)
|
target_link_libraries(${target_name} PRIVATE dbghelp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_UNWIND_WITH_NOTHING)
|
if(CPPTRACE_UNWIND_WITH_NOTHING)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_UNWIND_WITH_NOTHING)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_UNWIND_WITH_NOTHING)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Demangling
|
# Demangling
|
||||||
@ -360,100 +373,38 @@ if(CPPTRACE_DEMANGLE_WITH_CXXABI)
|
|||||||
if(NOT HAS_CXXABI)
|
if(NOT HAS_CXXABI)
|
||||||
message(WARNING "Cpptrace: CPPTRACE_DEMANGLE_WITH_CXXABI specified but cxxabi.h doesn't seem to be available.")
|
message(WARNING "Cpptrace: CPPTRACE_DEMANGLE_WITH_CXXABI specified but cxxabi.h doesn't seem to be available.")
|
||||||
endif()
|
endif()
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_DEMANGLE_WITH_CXXABI)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_DEMANGLE_WITH_CXXABI)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_DEMANGLE_WITH_WINAPI)
|
if(CPPTRACE_DEMANGLE_WITH_WINAPI)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_DEMANGLE_WITH_WINAPI)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_DEMANGLE_WITH_WINAPI)
|
||||||
target_link_libraries(cpptrace PRIVATE dbghelp)
|
target_link_libraries(${target_name} PRIVATE dbghelp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_DEMANGLE_WITH_NOTHING)
|
if(CPPTRACE_DEMANGLE_WITH_NOTHING)
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_DEMANGLE_WITH_NOTHING)
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_DEMANGLE_WITH_NOTHING)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT "${CPPTRACE_BACKTRACE_PATH}" STREQUAL "")
|
if(NOT "${CPPTRACE_BACKTRACE_PATH}" STREQUAL "")
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_BACKTRACE_PATH=${CPPTRACE_BACKTRACE_PATH})
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_BACKTRACE_PATH=${CPPTRACE_BACKTRACE_PATH})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT "${CPPTRACE_HARD_MAX_FRAMES}" STREQUAL "")
|
if(NOT "${CPPTRACE_HARD_MAX_FRAMES}" STREQUAL "")
|
||||||
target_compile_definitions(cpptrace PUBLIC CPPTRACE_HARD_MAX_FRAMES=${CPPTRACE_HARD_MAX_FRAMES})
|
target_compile_definitions(${target_name} PUBLIC CPPTRACE_HARD_MAX_FRAMES=${CPPTRACE_HARD_MAX_FRAMES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ======================================================================================================================
|
# =============================================== Install ===============================================
|
||||||
|
|
||||||
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||||
include(CMakePackageConfigHelpers)
|
include(cmake/InstallRules.cmake)
|
||||||
|
|
||||||
if(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF)
|
|
||||||
set(CPPTRACE_STATIC_EXPORT_TARGETS cpptrace dwarf)
|
|
||||||
else()
|
|
||||||
set(CPPTRACE_STATIC_EXPORT_TARGETS cpptrace)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CPPTRACE_STATIC)
|
# =============================================== Demo/test ===============================================
|
||||||
install(
|
|
||||||
TARGETS ${CPPTRACE_STATIC_EXPORT_TARGETS}
|
|
||||||
EXPORT cpptrace_targets
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
install(
|
|
||||||
TARGETS cpptrace
|
|
||||||
EXPORT cpptrace_targets
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(
|
|
||||||
FILES
|
|
||||||
include/cpptrace/cpptrace.hpp
|
|
||||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpptrace
|
|
||||||
)
|
|
||||||
|
|
||||||
export(
|
|
||||||
EXPORT cpptrace_targets
|
|
||||||
FILE ${CMAKE_CURRENT_BINARY_DIR}/cpptrace/cpptrace_targets.cmake
|
|
||||||
NAMESPACE cpptrace::
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_package_config_file(
|
|
||||||
cmake/cpptrace-config.cmake.in
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/cpptrace/cpptrace-config.cmake
|
|
||||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cpptrace
|
|
||||||
)
|
|
||||||
|
|
||||||
write_basic_package_version_file(
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/cpptrace/cpptrace-config-version.cmake
|
|
||||||
VERSION ${PACKAGE_VERSION}
|
|
||||||
COMPATIBILITY SameMajorVersion
|
|
||||||
)
|
|
||||||
|
|
||||||
install(
|
|
||||||
EXPORT cpptrace_targets
|
|
||||||
FILE cpptrace_targets.cmake
|
|
||||||
NAMESPACE cpptrace::
|
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cpptrace
|
|
||||||
)
|
|
||||||
|
|
||||||
install(
|
|
||||||
FILES
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/cpptrace/cpptrace-config.cmake
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/cpptrace/cpptrace-config-version.cmake
|
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cpptrace
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CPPTRACE_BUILD_TEST)
|
if(CPPTRACE_BUILD_TEST)
|
||||||
add_executable(test test/test.cpp)
|
add_executable(test test/test.cpp)
|
||||||
target_compile_features(test PRIVATE cxx_range_for cxx_constexpr cxx_nullptr cxx_static_assert)
|
target_compile_features(test PRIVATE cxx_range_for cxx_constexpr cxx_nullptr cxx_static_assert)
|
||||||
target_link_libraries(test PRIVATE cpptrace)
|
target_link_libraries(test PRIVATE ${target_name})
|
||||||
# Clang has been fast to adopt dwarf 5, other tools (e.g. addr2line from binutils) have not
|
# Clang has been fast to adopt dwarf 5, other tools (e.g. addr2line from binutils) have not
|
||||||
check_cxx_compiler_flag("-gdwarf-4" HAS_DWARF4)
|
check_cxx_compiler_flag("-gdwarf-4" HAS_DWARF4)
|
||||||
if(HAS_DWARF4)
|
if(HAS_DWARF4)
|
||||||
@ -474,7 +425,7 @@ endif()
|
|||||||
if(CPPTRACE_BUILD_DEMO)
|
if(CPPTRACE_BUILD_DEMO)
|
||||||
add_executable(demo test/demo.cpp)
|
add_executable(demo test/demo.cpp)
|
||||||
target_compile_features(demo PRIVATE cxx_range_for cxx_constexpr cxx_nullptr cxx_static_assert)
|
target_compile_features(demo PRIVATE cxx_range_for cxx_constexpr cxx_nullptr cxx_static_assert)
|
||||||
target_link_libraries(demo PRIVATE cpptrace)
|
target_link_libraries(demo PRIVATE ${target_name})
|
||||||
# Clang has been fast to adopt dwarf 5, other tools (e.g. addr2line from binutils) have not
|
# Clang has been fast to adopt dwarf 5, other tools (e.g. addr2line from binutils) have not
|
||||||
check_cxx_compiler_flag("-gdwarf-4" HAS_DWARF4)
|
check_cxx_compiler_flag("-gdwarf-4" HAS_DWARF4)
|
||||||
if(HAS_DWARF4)
|
if(HAS_DWARF4)
|
||||||
|
|||||||
11
README.md
11
README.md
@ -585,7 +585,7 @@ configurable with `CPPTRACE_HARD_MAX_FRAMES`.
|
|||||||
|
|
||||||
| Library | CMake config | Platforms | Info |
|
| Library | CMake config | Platforms | Info |
|
||||||
| ------------ | ---------------------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------ | ---------------------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| libdwarf | `CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF` | linux, macos, mingw | Libdwarf is the preferred method for symbol resolution for cpptrace, and it's bundled in this repository for ease of use. |
|
| libdwarf | `CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF` | linux, macos, mingw | Libdwarf is the preferred method for symbol resolution for cpptrace. Cpptrace will get it via FetchContent or find_package depending on `CPPTRACE_USE_EXTERNAL_LIBDWARF`. |
|
||||||
| dbghelp | `CPPTRACE_GET_SYMBOLS_WITH_DBGHELP` | windows | Dbghelp.h is the preferred method for symbol resolution on windows under msvc/clang and is supported on all windows machines. |
|
| dbghelp | `CPPTRACE_GET_SYMBOLS_WITH_DBGHELP` | windows | Dbghelp.h is the preferred method for symbol resolution on windows under msvc/clang and is supported on all windows machines. |
|
||||||
| libbacktrace | `CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE` | linux, macos*, mingw* | Libbacktrace is already installed on most systems or available through the compiler directly. For clang you must specify the absolute path to `backtrace.h` using `CPPTRACE_BACKTRACE_PATH`. |
|
| libbacktrace | `CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE` | linux, macos*, mingw* | Libbacktrace is already installed on most systems or available through the compiler directly. For clang you must specify the absolute path to `backtrace.h` using `CPPTRACE_BACKTRACE_PATH`. |
|
||||||
| addr2line | `CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE` | linux, macos, mingw | Symbols are resolved by invoking `addr2line` (or `atos` on mac) via `fork()` (on linux/unix, and `popen` under mingw). |
|
| addr2line | `CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE` | linux, macos, mingw | Symbols are resolved by invoking `addr2line` (or `atos` on mac) via `fork()` (on linux/unix, and `popen` under mingw). |
|
||||||
@ -634,7 +634,6 @@ Back-ends:
|
|||||||
- `CPPTRACE_DEMANGLE_WITH_NOTHING=On/Off`
|
- `CPPTRACE_DEMANGLE_WITH_NOTHING=On/Off`
|
||||||
|
|
||||||
Back-end configuration:
|
Back-end configuration:
|
||||||
- `CPPTRACE_STATIC=On/Off`: Create cpptrace as a static library.
|
|
||||||
- `CPPTRACE_BACKTRACE_PATH=<string>`: Path to libbacktrace backtrace.h, needed when compiling with clang/
|
- `CPPTRACE_BACKTRACE_PATH=<string>`: Path to libbacktrace backtrace.h, needed when compiling with clang/
|
||||||
- `CPPTRACE_HARD_MAX_FRAMES=<number>`: Some back-ends write to a fixed-size buffer. This is the size of that buffer.
|
- `CPPTRACE_HARD_MAX_FRAMES=<number>`: Some back-ends write to a fixed-size buffer. This is the size of that buffer.
|
||||||
Default is `100`.
|
Default is `100`.
|
||||||
@ -643,7 +642,13 @@ Back-end configuration:
|
|||||||
injection).
|
injection).
|
||||||
- `CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH=On/Off`: Specifies whether cpptrace should let the system search the PATH
|
- `CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH=On/Off`: Specifies whether cpptrace should let the system search the PATH
|
||||||
environment variable directories for the binary.
|
environment variable directories for the binary.
|
||||||
- `CPPTRACE_USE_SYSTEM_LIBDWARF=On/Off`: Use libdwarf resolved via `find_package` rather than the bundled libdwarf.
|
|
||||||
|
Other userufl configurations:
|
||||||
|
- `CPPTRACE_BUILD_SHARED=On/Off`: Override for `BUILD_SHARED_LIBS`.
|
||||||
|
- `CPPTRACE_INCLUDES_WITH_SYSTEM=On/Off`: Marks cpptrace headers as `SYSTEM` which will hide any warnings that aren't
|
||||||
|
the fault of your project. Defaults to On.
|
||||||
|
- `CPPTRACE_INSTALL_CMAKEDIR`: Override for the installation path for the cmake configs.
|
||||||
|
- `CPPTRACE_USE_EXTERNAL_LIBDWARF=On/Off`: Get libdwarf from `find_package` rather than `FetchContent`.
|
||||||
|
|
||||||
Testing:
|
Testing:
|
||||||
- `CPPTRACE_BUILD_TEST` Build a small test program
|
- `CPPTRACE_BUILD_TEST` Build a small test program
|
||||||
|
|||||||
94
bundled/libdwarf/CMakeLists.txt
vendored
94
bundled/libdwarf/CMakeLists.txt
vendored
@ -430,11 +430,17 @@ set(
|
|||||||
libdwarf_private.h
|
libdwarf_private.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(
|
||||||
|
libdwarf_export_headers
|
||||||
|
dwarf.h
|
||||||
|
libdwarf.h
|
||||||
|
)
|
||||||
|
|
||||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
add_library(dwarf OBJECT ${libdwarf_sources} ${libdwarf_headers})
|
add_library(dwarf STATIC ${libdwarf_sources} ${libdwarf_headers})
|
||||||
set_property(TARGET dwarf PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET dwarf PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
target_compile_definitions(dwarf PUBLIC LIBDWARF_BUILD)
|
target_compile_definitions(dwarf PUBLIC LIBDWARF_BUILD)
|
||||||
@ -452,53 +458,53 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO: Something will have to be figured out for dynamic linking, but for now there's nothing to install
|
# TODO: Something will have to be figured out for dynamic linking, but for now there's nothing to install
|
||||||
# if(NOT CMAKE_SKIP_INSTALL_RULES)
|
if(NOT CMAKE_SKIP_INSTALL_RULES)
|
||||||
# include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
# install(
|
install(
|
||||||
# TARGETS dwarf
|
TARGETS dwarf
|
||||||
# EXPORT libdwarf_targets
|
EXPORT libdwarf_targets
|
||||||
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
# INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
# RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
# )
|
)
|
||||||
|
|
||||||
# install(
|
install(
|
||||||
# FILES
|
FILES
|
||||||
# ${libdwarf_headers}
|
${libdwarf_export_headers}
|
||||||
# DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libdwarf
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libdwarf
|
||||||
# )
|
)
|
||||||
|
|
||||||
# export(
|
export(
|
||||||
# EXPORT libdwarf_targets
|
EXPORT libdwarf_targets
|
||||||
# FILE ${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf_targets.cmake
|
FILE ${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf_targets.cmake
|
||||||
# NAMESPACE libdwarf::
|
NAMESPACE libdwarf::
|
||||||
# )
|
)
|
||||||
|
|
||||||
# configure_package_config_file(
|
configure_package_config_file(
|
||||||
# cmake/libdwarf-config.cmake.in
|
cmake/libdwarf-config.cmake.in
|
||||||
# ${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf-config.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf-config.cmake
|
||||||
# INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf
|
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf
|
||||||
# )
|
)
|
||||||
|
|
||||||
# write_basic_package_version_file(
|
write_basic_package_version_file(
|
||||||
# ${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf-config-version.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf-config-version.cmake
|
||||||
# VERSION "${VERSION}"
|
VERSION "${VERSION}"
|
||||||
# COMPATIBILITY SameMajorVersion
|
COMPATIBILITY SameMajorVersion
|
||||||
# )
|
)
|
||||||
|
|
||||||
# install(
|
install(
|
||||||
# EXPORT libdwarf_targets
|
EXPORT libdwarf_targets
|
||||||
# FILE libdwarf_targets.cmake
|
FILE libdwarf_targets.cmake
|
||||||
# NAMESPACE libdwarf::
|
NAMESPACE libdwarf::
|
||||||
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf
|
||||||
# )
|
)
|
||||||
|
|
||||||
# install(
|
install(
|
||||||
# FILES
|
FILES
|
||||||
# ${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf-config.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf-config.cmake
|
||||||
# ${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf-config-version.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf-config-version.cmake
|
||||||
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf
|
||||||
# )
|
)
|
||||||
# endif()
|
endif()
|
||||||
|
|||||||
@ -15,6 +15,9 @@ failed = False
|
|||||||
|
|
||||||
expected_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../test/expected/")
|
expected_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../test/expected/")
|
||||||
|
|
||||||
|
def get_c_compiler_counterpart(compiler: str) -> str:
|
||||||
|
return compiler.replace("clang++", "clang").replace("g++", "gcc")
|
||||||
|
|
||||||
MAX_LINE_DIFF = 2
|
MAX_LINE_DIFF = 2
|
||||||
|
|
||||||
def similarity(name: str, target: List[str]) -> int:
|
def similarity(name: str, target: List[str]) -> int:
|
||||||
@ -149,6 +152,7 @@ def build(matrix):
|
|||||||
"..",
|
"..",
|
||||||
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
|
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
|
||||||
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
|
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
|
||||||
|
f"-DCMAKE_C_COMPILER={get_c_compiler_counterpart(matrix['compiler'])}",
|
||||||
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
|
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
|
||||||
f"-D{matrix['unwind']}=On",
|
f"-D{matrix['unwind']}=On",
|
||||||
f"-D{matrix['symbols']}=On",
|
f"-D{matrix['symbols']}=On",
|
||||||
@ -167,6 +171,7 @@ def build(matrix):
|
|||||||
"..",
|
"..",
|
||||||
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
|
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
|
||||||
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
|
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
|
||||||
|
f"-DCMAKE_C_COMPILER={get_c_compiler_counterpart(matrix['compiler'])}",
|
||||||
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
|
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
|
||||||
f"-D{matrix['unwind']}=On",
|
f"-D{matrix['unwind']}=On",
|
||||||
f"-D{matrix['symbols']}=On",
|
f"-D{matrix['symbols']}=On",
|
||||||
@ -190,6 +195,7 @@ def build_full_or_auto(matrix):
|
|||||||
"..",
|
"..",
|
||||||
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
|
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
|
||||||
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
|
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
|
||||||
|
f"-DCMAKE_C_COMPILER={get_c_compiler_counterpart(matrix['compiler'])}",
|
||||||
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
|
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
|
||||||
f"-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h",
|
f"-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h",
|
||||||
"-DCPPTRACE_BUILD_TEST=On"
|
"-DCPPTRACE_BUILD_TEST=On"
|
||||||
@ -205,6 +211,7 @@ def build_full_or_auto(matrix):
|
|||||||
"..",
|
"..",
|
||||||
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
|
f"-DCMAKE_BUILD_TYPE={matrix['target']}",
|
||||||
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
|
f"-DCMAKE_CXX_COMPILER={matrix['compiler']}",
|
||||||
|
f"-DCMAKE_C_COMPILER={get_c_compiler_counterpart(matrix['compiler'])}",
|
||||||
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
|
f"-DCMAKE_CXX_STANDARD={matrix['std']}",
|
||||||
"-DCPPTRACE_BUILD_TEST=On"
|
"-DCPPTRACE_BUILD_TEST=On"
|
||||||
]
|
]
|
||||||
@ -309,7 +316,8 @@ def main():
|
|||||||
#"CPPTRACE_UNWIND_WITH_NOTHING",
|
#"CPPTRACE_UNWIND_WITH_NOTHING",
|
||||||
],
|
],
|
||||||
"symbols": [
|
"symbols": [
|
||||||
"CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE",
|
# Disabled due to libbacktrace bug
|
||||||
|
# "CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE",
|
||||||
"CPPTRACE_GET_SYMBOLS_WITH_LIBDL",
|
"CPPTRACE_GET_SYMBOLS_WITH_LIBDL",
|
||||||
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE",
|
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE",
|
||||||
"CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF",
|
"CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF",
|
||||||
|
|||||||
69
cmake/InstallRules.cmake
Normal file
69
cmake/InstallRules.cmake
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
# copy header files to CMAKE_INSTALL_INCLUDEDIR
|
||||||
|
# don't include third party header files
|
||||||
|
install(
|
||||||
|
DIRECTORY
|
||||||
|
"${PROJECT_SOURCE_DIR}/include/" # our header files
|
||||||
|
"${PROJECT_BINARY_DIR}/include/" # generated header files
|
||||||
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
|
COMPONENT ${package_name}-development
|
||||||
|
# PATTERN "**/third_party" EXCLUDE # skip third party directory
|
||||||
|
# PATTERN "**/third_party/**" EXCLUDE # skip third party files
|
||||||
|
)
|
||||||
|
|
||||||
|
# copy target build output artifacts to OS dependent locations
|
||||||
|
# (Except includes, that just sets a compiler flag with the path)
|
||||||
|
install(
|
||||||
|
TARGETS ${target_name}
|
||||||
|
EXPORT ${package_name}-targets
|
||||||
|
RUNTIME #
|
||||||
|
COMPONENT ${package_name}-runtime
|
||||||
|
LIBRARY #
|
||||||
|
COMPONENT ${package_name}-runtime
|
||||||
|
NAMELINK_COMPONENT ${package_name}-development
|
||||||
|
ARCHIVE #
|
||||||
|
COMPONENT ${package_name}-development
|
||||||
|
INCLUDES #
|
||||||
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# create config file that points to targets file
|
||||||
|
configure_file(
|
||||||
|
"${PROJECT_SOURCE_DIR}/cmake/in/cpptrace-config-cmake.in"
|
||||||
|
"${PROJECT_BINARY_DIR}/cmake/${package_name}-config.cmake"
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
# copy config file for find_package to find
|
||||||
|
install(
|
||||||
|
FILES "${PROJECT_BINARY_DIR}/cmake/${package_name}-config.cmake"
|
||||||
|
DESTINATION "${CPPTRACE_INSTALL_CMAKEDIR}"
|
||||||
|
COMPONENT ${package_name}-development
|
||||||
|
)
|
||||||
|
|
||||||
|
# create version file for consumer to check version in CMake
|
||||||
|
write_basic_package_version_file(
|
||||||
|
"${package_name}-config-version.cmake"
|
||||||
|
COMPATIBILITY SameMajorVersion # a.k.a SemVer
|
||||||
|
)
|
||||||
|
|
||||||
|
# copy version file for find_package to find for version check
|
||||||
|
install(
|
||||||
|
FILES "${PROJECT_BINARY_DIR}/${package_name}-config-version.cmake"
|
||||||
|
DESTINATION "${CPPTRACE_INSTALL_CMAKEDIR}"
|
||||||
|
COMPONENT ${package_name}-development
|
||||||
|
)
|
||||||
|
|
||||||
|
# create targets file included by config file with targets for consumers
|
||||||
|
install(
|
||||||
|
EXPORT ${package_name}-targets
|
||||||
|
NAMESPACE cpptrace::
|
||||||
|
DESTINATION "${CPPTRACE_INSTALL_CMAKEDIR}"
|
||||||
|
COMPONENT ${package_name}-development
|
||||||
|
)
|
||||||
|
|
||||||
|
# support packaging library
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
include(CPack)
|
||||||
|
endif()
|
||||||
170
cmake/OptionVariables.cmake
Normal file
170
cmake/OptionVariables.cmake
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
# Included further down to avoid interfering with our cache variables
|
||||||
|
# include(GNUInstallDirs)
|
||||||
|
|
||||||
|
# ---- Options Summary ----
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------------------------------
|
||||||
|
# | Option | Availability | Default |
|
||||||
|
# |=================================|===============|===============================================|
|
||||||
|
# | BUILD_SHARED_LIBS | Top-Level | OFF |
|
||||||
|
# | BUILD_TESTING | Top-Level | OFF |
|
||||||
|
# | CMAKE_INSTALL_INCLUDEDIR | Top-Level | include/${package_name}-${PROJECT_VERSION} |
|
||||||
|
# |---------------------------------|---------------|-----------------------------------------------|
|
||||||
|
# | ASSERT_BUILD_SHARED | Always | ${BUILD_SHARED_LIBS} |
|
||||||
|
# | ASSERT_BUILD_TESTING | Always | ${BUILD_TESTING} AND ${PROJECT_IS_TOP_LEVEL} |
|
||||||
|
# | ASSERT_INCLUDES_WITH_SYSTEM | Not Top-Level | ON |
|
||||||
|
# | ASSERT_INSTALL_CMAKEDIR | Always | ${CMAKE_INSTALL_LIBDIR}/cmake/${package_name} |
|
||||||
|
# | CPPTRACE_USE_EXTERNAL_LIBDWARF | Always | OFF |
|
||||||
|
# | ... | | |
|
||||||
|
# ---------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ---- Build Shared ----
|
||||||
|
|
||||||
|
# Sometimes it's useful to be able to single out a dependency to be built as
|
||||||
|
# static or shared, even if obtained from source
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
option(BUILD_SHARED_LIBS "Build shared libs" OFF)
|
||||||
|
endif()
|
||||||
|
option(
|
||||||
|
CPPTRACE_BUILD_SHARED
|
||||||
|
"Override BUILD_SHARED_LIBS for ${package_name} library"
|
||||||
|
${BUILD_SHARED_LIBS}
|
||||||
|
)
|
||||||
|
mark_as_advanced(CPPTRACE_BUILD_SHARED)
|
||||||
|
set(build_type STATIC)
|
||||||
|
if(CPPTRACE_BUILD_SHARED)
|
||||||
|
set(build_type SHARED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ---- Warning Guard ----
|
||||||
|
|
||||||
|
# target_include_directories with SYSTEM modifier will request the compiler to
|
||||||
|
# omit warnings from the provided paths, if the compiler supports that.
|
||||||
|
# This is to provide a user experience similar to find_package when
|
||||||
|
# add_subdirectory or FetchContent is used to consume this project.
|
||||||
|
set(warning_guard )
|
||||||
|
if(NOT PROJECT_IS_TOP_LEVEL)
|
||||||
|
option(
|
||||||
|
CPPTRACE_INCLUDES_WITH_SYSTEM
|
||||||
|
"Use SYSTEM modifier for ${package_name}'s includes, disabling warnings"
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
mark_as_advanced(CPPTRACE_INCLUDES_WITH_SYSTEM)
|
||||||
|
if(CPPTRACE_INCLUDES_WITH_SYSTEM)
|
||||||
|
set(warning_guard SYSTEM)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ---- Enable Testing ----
|
||||||
|
|
||||||
|
# By default tests aren't enabled even with BUILD_TESTING=ON unless the library
|
||||||
|
# is built as a top level project.
|
||||||
|
# This is in order to cut down on unnecessary compile times, since it's unlikely
|
||||||
|
# for users to want to run the tests of their dependencies.
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
option(BUILD_TESTING "Build tests" OFF)
|
||||||
|
endif()
|
||||||
|
if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
|
||||||
|
set(build_testing ON)
|
||||||
|
endif()
|
||||||
|
option(
|
||||||
|
CPPTRACE_BUILD_TESTING
|
||||||
|
"Override BUILD_TESTING for ${package_name} library"
|
||||||
|
${build_testing}
|
||||||
|
)
|
||||||
|
set(build_testing )
|
||||||
|
mark_as_advanced(CPPTRACE_BUILD_TESTING)
|
||||||
|
|
||||||
|
# ---- Install Include Directory ----
|
||||||
|
|
||||||
|
# Adds an extra directory to the include path by default, so that when you link
|
||||||
|
# against the target, you get `<prefix>/include/<package-X.Y.Z>` added to your
|
||||||
|
# include paths rather than `<prefix>/include`.
|
||||||
|
# This doesn't affect include paths used by consumers of this project, but helps
|
||||||
|
# prevent consumers having access to other projects in the same include
|
||||||
|
# directory (e.g. usr/include).
|
||||||
|
# The variable type is STRING rather than PATH, because otherwise passing
|
||||||
|
# -DCMAKE_INSTALL_INCLUDEDIR=include on the command line would expand to an
|
||||||
|
# absolute path with the base being the current CMake directory, leading to
|
||||||
|
# unexpected errors.
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
set(
|
||||||
|
CMAKE_INSTALL_INCLUDEDIR "include/${package_name}-${PROJECT_VERSION}"
|
||||||
|
CACHE STRING ""
|
||||||
|
)
|
||||||
|
# marked as advanced in GNUInstallDirs version, so we follow their lead
|
||||||
|
mark_as_advanced(CMAKE_INSTALL_INCLUDEDIR)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# do not include earlier or we can't set CMAKE_INSTALL_INCLUDEDIR above
|
||||||
|
# include required for CMAKE_INSTALL_LIBDIR below
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
# ---- Install CMake Directory ----
|
||||||
|
|
||||||
|
# This allows package maintainers to freely override the installation path for
|
||||||
|
# the CMake configs.
|
||||||
|
# This doesn't affects include paths used by consumers of this project.
|
||||||
|
# The variable type is STRING rather than PATH, because otherwise passing
|
||||||
|
# -DCPPTRACE_INSTALL_CMAKEDIR=lib/cmake on the command line would expand to an
|
||||||
|
# absolute path with the base being the current CMake directory, leading to
|
||||||
|
# unexpected errors.
|
||||||
|
set(
|
||||||
|
CPPTRACE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${package_name}"
|
||||||
|
CACHE STRING "CMake package config location relative to the install prefix"
|
||||||
|
)
|
||||||
|
# depends on CMAKE_INSTALL_LIBDIR which is marked as advanced in GNUInstallDirs
|
||||||
|
mark_as_advanced(CPPTRACE_INSTALL_CMAKEDIR)
|
||||||
|
|
||||||
|
# ---- Symbol Options ----
|
||||||
|
|
||||||
|
option(CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE "" OFF)
|
||||||
|
option(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF "" OFF)
|
||||||
|
option(CPPTRACE_GET_SYMBOLS_WITH_LIBDL "" OFF)
|
||||||
|
option(CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE "" OFF)
|
||||||
|
option(CPPTRACE_GET_SYMBOLS_WITH_DBGHELP "" OFF)
|
||||||
|
option(CPPTRACE_GET_SYMBOLS_WITH_NOTHING "" OFF)
|
||||||
|
|
||||||
|
# ---- Unwinding Options ----
|
||||||
|
|
||||||
|
option(CPPTRACE_UNWIND_WITH_UNWIND "" OFF)
|
||||||
|
option(CPPTRACE_UNWIND_WITH_EXECINFO "" OFF)
|
||||||
|
option(CPPTRACE_UNWIND_WITH_WINAPI "" OFF)
|
||||||
|
option(CPPTRACE_UNWIND_WITH_DBGHELP "" OFF)
|
||||||
|
option(CPPTRACE_UNWIND_WITH_NOTHING "" OFF)
|
||||||
|
|
||||||
|
# ---- Demangling Options ----
|
||||||
|
|
||||||
|
option(CPPTRACE_DEMANGLE_WITH_CXXABI "" OFF)
|
||||||
|
option(CPPTRACE_DEMANGLE_WITH_WINAPI "" OFF)
|
||||||
|
option(CPPTRACE_DEMANGLE_WITH_NOTHING "" OFF)
|
||||||
|
|
||||||
|
# ---- Back-end configurations ----
|
||||||
|
|
||||||
|
set(CPPTRACE_BACKTRACE_PATH "" CACHE STRING "Path to backtrace.h, if the compiler doesn't already know it. Check /usr/lib/gcc/x86_64-linux-gnu/*/include.")
|
||||||
|
set(CPPTRACE_HARD_MAX_FRAMES "" CACHE STRING "Hard limit on unwinding depth. Default is 100.")
|
||||||
|
set(CPPTRACE_ADDR2LINE_PATH "" CACHE STRING "Absolute path to the addr2line executable you want to use.")
|
||||||
|
option(CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH "" OFF)
|
||||||
|
|
||||||
|
# ---- Other configurations ----
|
||||||
|
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
option(CPPTRACE_BUILD_TEST "" OFF)
|
||||||
|
option(CPPTRACE_BUILD_DEMO "" OFF)
|
||||||
|
option(CPPTRACE_BUILD_TEST_RDYNAMIC "" OFF)
|
||||||
|
mark_as_advanced(
|
||||||
|
CPPTRACE_BUILD_TEST
|
||||||
|
CPPTRACE_BUILD_DEMO
|
||||||
|
CPPTRACE_BUILD_TEST_RDYNAMIC
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(CPPTRACE_USE_EXTERNAL_LIBDWARF "" OFF)
|
||||||
|
option(CPPTRACE_SANITIZER_BUILD "" OFF)
|
||||||
|
|
||||||
|
mark_as_advanced(
|
||||||
|
CPPTRACE_BACKTRACE_PATH
|
||||||
|
CPPTRACE_ADDR2LINE_PATH
|
||||||
|
CPPTRACE_ADDR2LINE_SEARCH_SYSTEM_PATH
|
||||||
|
CPPTRACE_SANITIZER_BUILD
|
||||||
|
)
|
||||||
8
cmake/PreventInSourceBuilds.cmake
Normal file
8
cmake/PreventInSourceBuilds.cmake
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# In-source build guard
|
||||||
|
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||||
|
message(
|
||||||
|
FATAL_ERROR
|
||||||
|
"In-source builds are not supported. "
|
||||||
|
"You may need to delete 'CMakeCache.txt' and 'CMakeFiles/' before rebuilding this project."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
6
cmake/ProjectIsTopLevel.cmake
Normal file
6
cmake/ProjectIsTopLevel.cmake
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# This variable is set by project() in CMake 3.21+
|
||||||
|
string(
|
||||||
|
COMPARE EQUAL
|
||||||
|
"${CMAKE_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}"
|
||||||
|
PROJECT_IS_TOP_LEVEL
|
||||||
|
)
|
||||||
@ -1,3 +0,0 @@
|
|||||||
@PACKAGE_INIT@
|
|
||||||
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/cpptrace_targets.cmake)
|
|
||||||
9
cmake/has_backtrace.cpp
Normal file
9
cmake/has_backtrace.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifdef CPPTRACE_BACKTRACE_PATH
|
||||||
|
#include CPPTRACE_BACKTRACE_PATH
|
||||||
|
#else
|
||||||
|
#include <backtrace.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
backtrace_state* state = backtrace_create_state(nullptr, true, nullptr, nullptr);
|
||||||
|
}
|
||||||
14
cmake/in/cpptrace-config-cmake.in
Normal file
14
cmake/in/cpptrace-config-cmake.in
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Init @ variables before doing anything else
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
find_dependency(libdwarf REQUIRED)
|
||||||
|
|
||||||
|
# We cannot modify an existing IMPORT target
|
||||||
|
if(NOT TARGET assert::assert)
|
||||||
|
|
||||||
|
# import targets
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/@package_name@-targets.cmake")
|
||||||
|
|
||||||
|
endif()
|
||||||
@ -7,6 +7,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "cpptrace/cpptrace_export.hpp"
|
||||||
|
|
||||||
#if __cplusplus >= 202002L
|
#if __cplusplus >= 202002L
|
||||||
#ifdef __has_include
|
#ifdef __has_include
|
||||||
#if __has_include(<format>)
|
#if __has_include(<format>)
|
||||||
@ -16,24 +18,18 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
|
||||||
#define CPPTRACE_API __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define CPPTRACE_API
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace cpptrace {
|
namespace cpptrace {
|
||||||
struct object_trace;
|
struct object_trace;
|
||||||
struct stacktrace;
|
struct stacktrace;
|
||||||
|
|
||||||
struct raw_trace {
|
struct CPPTRACE_EXPORT raw_trace {
|
||||||
std::vector<std::uintptr_t> frames;
|
std::vector<std::uintptr_t> frames;
|
||||||
CPPTRACE_API static raw_trace current(std::uint_least32_t skip = 0);
|
static raw_trace current(std::uint_least32_t skip = 0);
|
||||||
CPPTRACE_API static raw_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
static raw_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
CPPTRACE_API object_trace resolve_object_trace() const;
|
object_trace resolve_object_trace() const;
|
||||||
CPPTRACE_API stacktrace resolve() const;
|
stacktrace resolve() const;
|
||||||
CPPTRACE_API void clear();
|
void clear();
|
||||||
CPPTRACE_API bool empty() const noexcept;
|
bool empty() const noexcept;
|
||||||
|
|
||||||
using iterator = std::vector<std::uintptr_t>::iterator;
|
using iterator = std::vector<std::uintptr_t>::iterator;
|
||||||
using const_iterator = std::vector<std::uintptr_t>::const_iterator;
|
using const_iterator = std::vector<std::uintptr_t>::const_iterator;
|
||||||
@ -45,20 +41,20 @@ namespace cpptrace {
|
|||||||
inline const_iterator cend() const noexcept { return frames.cend(); }
|
inline const_iterator cend() const noexcept { return frames.cend(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct object_frame {
|
struct CPPTRACE_EXPORT object_frame {
|
||||||
std::string obj_path;
|
std::string obj_path;
|
||||||
std::string symbol;
|
std::string symbol;
|
||||||
std::uintptr_t raw_address = 0;
|
std::uintptr_t raw_address = 0;
|
||||||
std::uintptr_t obj_address = 0;
|
std::uintptr_t obj_address = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct object_trace {
|
struct CPPTRACE_EXPORT object_trace {
|
||||||
std::vector<object_frame> frames;
|
std::vector<object_frame> frames;
|
||||||
CPPTRACE_API static object_trace current(std::uint_least32_t skip = 0);
|
static object_trace current(std::uint_least32_t skip = 0);
|
||||||
CPPTRACE_API static object_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
static object_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
CPPTRACE_API stacktrace resolve() const;
|
stacktrace resolve() const;
|
||||||
CPPTRACE_API void clear();
|
void clear();
|
||||||
CPPTRACE_API bool empty() const noexcept;
|
bool empty() const noexcept;
|
||||||
|
|
||||||
using iterator = std::vector<object_frame>::iterator;
|
using iterator = std::vector<object_frame>::iterator;
|
||||||
using const_iterator = std::vector<object_frame>::const_iterator;
|
using const_iterator = std::vector<object_frame>::const_iterator;
|
||||||
@ -70,7 +66,7 @@ namespace cpptrace {
|
|||||||
inline const_iterator cend() const noexcept { return frames.cend(); }
|
inline const_iterator cend() const noexcept { return frames.cend(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stacktrace_frame {
|
struct CPPTRACE_EXPORT stacktrace_frame {
|
||||||
std::uintptr_t address;
|
std::uintptr_t address;
|
||||||
std::uint_least32_t line; // TODO: This should use UINT_LEAST32_MAX as a sentinel
|
std::uint_least32_t line; // TODO: This should use UINT_LEAST32_MAX as a sentinel
|
||||||
std::uint_least32_t column; // UINT_LEAST32_MAX if not present
|
std::uint_least32_t column; // UINT_LEAST32_MAX if not present
|
||||||
@ -89,21 +85,21 @@ namespace cpptrace {
|
|||||||
return !operator==(other);
|
return !operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API std::string to_string() const;
|
std::string to_string() const;
|
||||||
CPPTRACE_API friend std::ostream& operator<<(std::ostream& stream, const stacktrace_frame& frame);
|
friend std::ostream& operator<<(std::ostream& stream, const stacktrace_frame& frame);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stacktrace {
|
struct CPPTRACE_EXPORT stacktrace {
|
||||||
std::vector<stacktrace_frame> frames;
|
std::vector<stacktrace_frame> frames;
|
||||||
CPPTRACE_API static stacktrace current(std::uint_least32_t skip = 0);
|
static stacktrace current(std::uint_least32_t skip = 0);
|
||||||
CPPTRACE_API static stacktrace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
static stacktrace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
CPPTRACE_API void print() const;
|
void print() const;
|
||||||
CPPTRACE_API void print(std::ostream& stream) const;
|
void print(std::ostream& stream) const;
|
||||||
CPPTRACE_API void print(std::ostream& stream, bool color) const;
|
void print(std::ostream& stream, bool color) const;
|
||||||
CPPTRACE_API void clear();
|
void clear();
|
||||||
CPPTRACE_API bool empty() const noexcept;
|
bool empty() const noexcept;
|
||||||
CPPTRACE_API std::string to_string(bool color = false) const;
|
std::string to_string(bool color = false) const;
|
||||||
CPPTRACE_API friend std::ostream& operator<<(std::ostream& stream, const stacktrace& trace);
|
friend std::ostream& operator<<(std::ostream& stream, const stacktrace& trace);
|
||||||
|
|
||||||
using iterator = std::vector<stacktrace_frame>::iterator;
|
using iterator = std::vector<stacktrace_frame>::iterator;
|
||||||
using const_iterator = std::vector<stacktrace_frame>::const_iterator;
|
using const_iterator = std::vector<stacktrace_frame>::const_iterator;
|
||||||
@ -114,27 +110,27 @@ namespace cpptrace {
|
|||||||
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
|
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
|
||||||
inline const_iterator cend() const noexcept { return frames.cend(); }
|
inline const_iterator cend() const noexcept { return frames.cend(); }
|
||||||
private:
|
private:
|
||||||
CPPTRACE_API void print(std::ostream& stream, bool color, bool newline_at_end, const char* header) const;
|
void print(std::ostream& stream, bool color, bool newline_at_end, const char* header) const;
|
||||||
friend void print_terminate_trace();
|
friend void print_terminate_trace();
|
||||||
};
|
};
|
||||||
|
|
||||||
CPPTRACE_API raw_trace generate_raw_trace(std::uint_least32_t skip = 0);
|
CPPTRACE_EXPORT raw_trace generate_raw_trace(std::uint_least32_t skip = 0);
|
||||||
CPPTRACE_API raw_trace generate_raw_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
CPPTRACE_EXPORT raw_trace generate_raw_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
CPPTRACE_API object_trace generate_object_trace(std::uint_least32_t skip = 0);
|
CPPTRACE_EXPORT object_trace generate_object_trace(std::uint_least32_t skip = 0);
|
||||||
CPPTRACE_API object_trace generate_object_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
CPPTRACE_EXPORT object_trace generate_object_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
CPPTRACE_API stacktrace generate_trace(std::uint_least32_t skip = 0);
|
CPPTRACE_EXPORT stacktrace generate_trace(std::uint_least32_t skip = 0);
|
||||||
CPPTRACE_API stacktrace generate_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
CPPTRACE_EXPORT stacktrace generate_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
|
|
||||||
// utilities:
|
// utilities:
|
||||||
CPPTRACE_API std::string demangle(const std::string& name);
|
CPPTRACE_EXPORT std::string demangle(const std::string& name);
|
||||||
CPPTRACE_API void absorb_trace_exceptions(bool absorb);
|
CPPTRACE_EXPORT void absorb_trace_exceptions(bool absorb);
|
||||||
CPPTRACE_API bool isatty(int fd);
|
CPPTRACE_EXPORT bool isatty(int fd);
|
||||||
|
|
||||||
CPPTRACE_API extern const int stdin_fileno;
|
CPPTRACE_EXPORT extern const int stdin_fileno;
|
||||||
CPPTRACE_API extern const int stderr_fileno;
|
CPPTRACE_EXPORT extern const int stderr_fileno;
|
||||||
CPPTRACE_API extern const int stdout_fileno;
|
CPPTRACE_EXPORT extern const int stdout_fileno;
|
||||||
|
|
||||||
CPPTRACE_API void register_terminate_handler();
|
CPPTRACE_EXPORT void register_terminate_handler();
|
||||||
|
|
||||||
enum class cache_mode {
|
enum class cache_mode {
|
||||||
// Only minimal lookup tables
|
// Only minimal lookup tables
|
||||||
@ -146,15 +142,15 @@ namespace cpptrace {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace experimental {
|
namespace experimental {
|
||||||
CPPTRACE_API void set_cache_mode(cache_mode mode);
|
CPPTRACE_EXPORT void set_cache_mode(cache_mode mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
CPPTRACE_API bool should_absorb_trace_exceptions();
|
CPPTRACE_EXPORT bool should_absorb_trace_exceptions();
|
||||||
CPPTRACE_API enum cache_mode get_cache_mode();
|
CPPTRACE_EXPORT enum cache_mode get_cache_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
class exception : public std::exception {
|
class CPPTRACE_EXPORT exception : public std::exception {
|
||||||
mutable raw_trace trace;
|
mutable raw_trace trace;
|
||||||
mutable stacktrace resolved_trace;
|
mutable stacktrace resolved_trace;
|
||||||
mutable std::string what_string;
|
mutable std::string what_string;
|
||||||
@ -177,7 +173,7 @@ namespace cpptrace {
|
|||||||
const stacktrace& get_trace() const noexcept;
|
const stacktrace& get_trace() const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
class exception_with_message : public exception {
|
class CPPTRACE_EXPORT exception_with_message : public exception {
|
||||||
mutable std::string message;
|
mutable std::string message;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -28,17 +28,16 @@
|
|||||||
#define CYAN ESC "36m"
|
#define CYAN ESC "36m"
|
||||||
|
|
||||||
namespace cpptrace {
|
namespace cpptrace {
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
raw_trace raw_trace::current(std::uint_least32_t skip) {
|
raw_trace raw_trace::current(std::uint_least32_t skip) {
|
||||||
return generate_raw_trace(skip + 1);
|
return generate_raw_trace(skip + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
raw_trace raw_trace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
raw_trace raw_trace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
return generate_raw_trace(skip + 1, max_depth);
|
return generate_raw_trace(skip + 1, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
object_trace raw_trace::resolve_object_trace() const {
|
object_trace raw_trace::resolve_object_trace() const {
|
||||||
try {
|
try {
|
||||||
return object_trace{detail::get_frames_object_info(frames)};
|
return object_trace{detail::get_frames_object_info(frames)};
|
||||||
@ -50,7 +49,6 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
stacktrace raw_trace::resolve() const {
|
stacktrace raw_trace::resolve() const {
|
||||||
try {
|
try {
|
||||||
std::vector<stacktrace_frame> trace = detail::resolve_frames(frames);
|
std::vector<stacktrace_frame> trace = detail::resolve_frames(frames);
|
||||||
@ -66,27 +64,24 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
void raw_trace::clear() {
|
void raw_trace::clear() {
|
||||||
frames.clear();
|
frames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
bool raw_trace::empty() const noexcept {
|
bool raw_trace::empty() const noexcept {
|
||||||
return frames.empty();
|
return frames.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
object_trace object_trace::current(std::uint_least32_t skip) {
|
object_trace object_trace::current(std::uint_least32_t skip) {
|
||||||
return generate_object_trace(skip + 1);
|
return generate_object_trace(skip + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
object_trace object_trace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
object_trace object_trace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
return generate_object_trace(skip + 1, max_depth);
|
return generate_object_trace(skip + 1, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
stacktrace object_trace::resolve() const {
|
stacktrace object_trace::resolve() const {
|
||||||
try {
|
try {
|
||||||
return stacktrace{detail::resolve_frames(frames)};
|
return stacktrace{detail::resolve_frames(frames)};
|
||||||
@ -98,23 +93,21 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
void object_trace::clear() {
|
void object_trace::clear() {
|
||||||
frames.clear();
|
frames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
bool object_trace::empty() const noexcept {
|
bool object_trace::empty() const noexcept {
|
||||||
return frames.empty();
|
return frames.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API std::string stacktrace_frame::to_string() const {
|
std::string stacktrace_frame::to_string() const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << *this;
|
oss << *this;
|
||||||
return std::move(oss).str();
|
return std::move(oss).str();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API std::ostream& operator<<(std::ostream& stream, const stacktrace_frame& frame) {
|
std::ostream& operator<<(std::ostream& stream, const stacktrace_frame& frame) {
|
||||||
stream
|
stream
|
||||||
<< std::hex
|
<< std::hex
|
||||||
<< "0x"
|
<< "0x"
|
||||||
@ -138,32 +131,28 @@ namespace cpptrace {
|
|||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
stacktrace stacktrace::current(std::uint32_t skip) {
|
stacktrace stacktrace::current(std::uint32_t skip) {
|
||||||
return generate_trace(skip + 1);
|
return generate_trace(skip + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
stacktrace stacktrace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
stacktrace stacktrace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
return generate_trace(skip + 1, max_depth);
|
return generate_trace(skip + 1, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
void stacktrace::print() const {
|
void stacktrace::print() const {
|
||||||
print(std::cerr, true);
|
print(std::cerr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
void stacktrace::print(std::ostream& stream) const {
|
void stacktrace::print(std::ostream& stream) const {
|
||||||
print(stream, true);
|
print(stream, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
void stacktrace::print(std::ostream& stream, bool color) const {
|
void stacktrace::print(std::ostream& stream, bool color) const {
|
||||||
print(stream, color, true, nullptr);
|
print(stream, color, true, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
void stacktrace::print(std::ostream& stream, bool color, bool newline_at_end, const char* header) const {
|
void stacktrace::print(std::ostream& stream, bool color, bool newline_at_end, const char* header) const {
|
||||||
if(color) {
|
if(color) {
|
||||||
detail::enable_virtual_terminal_processing_if_needed();
|
detail::enable_virtual_terminal_processing_if_needed();
|
||||||
@ -224,28 +213,25 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
void stacktrace::clear() {
|
void stacktrace::clear() {
|
||||||
frames.clear();
|
frames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
bool stacktrace::empty() const noexcept {
|
bool stacktrace::empty() const noexcept {
|
||||||
return frames.empty();
|
return frames.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
std::string stacktrace::to_string(bool color) const {
|
std::string stacktrace::to_string(bool color) const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
print(oss, color, false, nullptr);
|
print(oss, color, false, nullptr);
|
||||||
return std::move(oss).str();
|
return std::move(oss).str();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API std::ostream& operator<<(std::ostream& stream, const stacktrace& trace) {
|
std::ostream& operator<<(std::ostream& stream, const stacktrace& trace) {
|
||||||
return stream << trace.to_string();
|
return stream << trace.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
raw_trace generate_raw_trace(std::uint_least32_t skip) {
|
raw_trace generate_raw_trace(std::uint_least32_t skip) {
|
||||||
try {
|
try {
|
||||||
return raw_trace{detail::capture_frames(skip + 1, UINT_LEAST32_MAX)};
|
return raw_trace{detail::capture_frames(skip + 1, UINT_LEAST32_MAX)};
|
||||||
@ -257,7 +243,7 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
raw_trace generate_raw_trace(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
raw_trace generate_raw_trace(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
try {
|
try {
|
||||||
return raw_trace{detail::capture_frames(skip + 1, max_depth)};
|
return raw_trace{detail::capture_frames(skip + 1, max_depth)};
|
||||||
@ -269,7 +255,7 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
object_trace generate_object_trace(std::uint_least32_t skip) {
|
object_trace generate_object_trace(std::uint_least32_t skip) {
|
||||||
try {
|
try {
|
||||||
return object_trace{detail::get_frames_object_info(detail::capture_frames(skip + 1, UINT_LEAST32_MAX))};
|
return object_trace{detail::get_frames_object_info(detail::capture_frames(skip + 1, UINT_LEAST32_MAX))};
|
||||||
@ -281,7 +267,7 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
object_trace generate_object_trace(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
object_trace generate_object_trace(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
try {
|
try {
|
||||||
return object_trace{detail::get_frames_object_info(detail::capture_frames(skip + 1, max_depth))};
|
return object_trace{detail::get_frames_object_info(detail::capture_frames(skip + 1, max_depth))};
|
||||||
@ -293,12 +279,12 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
stacktrace generate_trace(std::uint_least32_t skip) {
|
stacktrace generate_trace(std::uint_least32_t skip) {
|
||||||
return generate_trace(skip + 1, UINT_LEAST32_MAX);
|
return generate_trace(skip + 1, UINT_LEAST32_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
stacktrace generate_trace(std::uint32_t skip, std::uint_least32_t max_depth) {
|
stacktrace generate_trace(std::uint32_t skip, std::uint_least32_t max_depth) {
|
||||||
try {
|
try {
|
||||||
std::vector<std::uintptr_t> frames = detail::capture_frames(skip + 1, max_depth);
|
std::vector<std::uintptr_t> frames = detail::capture_frames(skip + 1, max_depth);
|
||||||
@ -315,19 +301,17 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
std::string demangle(const std::string& name) {
|
std::string demangle(const std::string& name) {
|
||||||
return detail::demangle(name);
|
return detail::demangle(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
|
||||||
bool isatty(int fd) {
|
bool isatty(int fd) {
|
||||||
return detail::isatty(fd);
|
return detail::isatty(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API extern const int stdin_fileno = detail::fileno(stdin);
|
extern const int stdin_fileno = detail::fileno(stdin);
|
||||||
CPPTRACE_API extern const int stdout_fileno = detail::fileno(stdout);
|
extern const int stdout_fileno = detail::fileno(stdout);
|
||||||
CPPTRACE_API extern const int stderr_fileno = detail::fileno(stderr);
|
extern const int stderr_fileno = detail::fileno(stderr);
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE void print_terminate_trace() {
|
CPPTRACE_FORCE_NO_INLINE void print_terminate_trace() {
|
||||||
generate_trace(1).print(
|
generate_trace(1).print(
|
||||||
@ -338,7 +322,7 @@ namespace cpptrace {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] CPPTRACE_API void terminate_handler() {
|
[[noreturn]] void terminate_handler() {
|
||||||
try {
|
try {
|
||||||
auto ptr = std::current_exception();
|
auto ptr = std::current_exception();
|
||||||
if(ptr == nullptr) {
|
if(ptr == nullptr) {
|
||||||
@ -371,7 +355,7 @@ namespace cpptrace {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API void register_terminate_handler() {
|
void register_terminate_handler() {
|
||||||
std::set_terminate(terminate_handler);
|
std::set_terminate(terminate_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,22 +364,22 @@ namespace cpptrace {
|
|||||||
std::atomic<enum cache_mode> cache_mode(cache_mode::prioritize_speed); // NOSONAR
|
std::atomic<enum cache_mode> cache_mode(cache_mode::prioritize_speed); // NOSONAR
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API void absorb_trace_exceptions(bool absorb) {
|
void absorb_trace_exceptions(bool absorb) {
|
||||||
detail::absorb_trace_exceptions = absorb;
|
detail::absorb_trace_exceptions = absorb;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace experimental {
|
namespace experimental {
|
||||||
CPPTRACE_API void set_cache_mode(cache_mode mode) {
|
void set_cache_mode(cache_mode mode) {
|
||||||
detail::cache_mode = mode;
|
detail::cache_mode = mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
CPPTRACE_API bool should_absorb_trace_exceptions() {
|
bool should_absorb_trace_exceptions() {
|
||||||
return absorb_trace_exceptions;
|
return absorb_trace_exceptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API enum cache_mode get_cache_mode() {
|
enum cache_mode get_cache_mode() {
|
||||||
return cache_mode;
|
return cache_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,14 +5,14 @@ project(demo_project VERSION 0.0.1 LANGUAGES CXX)
|
|||||||
add_executable(main main.cpp)
|
add_executable(main main.cpp)
|
||||||
|
|
||||||
add_subdirectory(cpptrace)
|
add_subdirectory(cpptrace)
|
||||||
target_link_libraries(main cpptrace)
|
target_link_libraries(main cpptrace::cpptrace)
|
||||||
target_compile_features(main PRIVATE cxx_std_11)
|
target_compile_features(main PRIVATE cxx_std_11)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET main POST_BUILD
|
TARGET main POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
$<TARGET_FILE:cpptrace>
|
$<TARGET_FILE:cpptrace::cpptrace>
|
||||||
$<TARGET_FILE_DIR:main>
|
$<TARGET_FILE_DIR:main>
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -20,7 +20,7 @@ if(WIN32)
|
|||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET main POST_BUILD
|
TARGET main POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
$<TARGET_FILE:cpptrace>
|
$<TARGET_FILE:cpptrace::cpptrace>
|
||||||
$<TARGET_FILE_DIR:main>
|
$<TARGET_FILE_DIR:main>
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -35,6 +35,7 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
|||||||
FetchContent_MakeAvailable(googletest)
|
FetchContent_MakeAvailable(googletest)
|
||||||
|
|
||||||
set(cpptrace_DIR "../../build/foo/lib/cmake/cpptrace")
|
set(cpptrace_DIR "../../build/foo/lib/cmake/cpptrace")
|
||||||
|
set(libdwarf_DIR "../../build/foo/lib/cmake/libdwarf")
|
||||||
find_package(cpptrace REQUIRED)
|
find_package(cpptrace REQUIRED)
|
||||||
|
|
||||||
add_executable(speedtest speedtest.cpp)
|
add_executable(speedtest speedtest.cpp)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user