Skip to content

Commit

Permalink
Merge pull request #310 from lahwaacz/master
Browse files Browse the repository at this point in the history
CMake modernization: add Backward::Interface and Backward::Object targets
  • Loading branch information
bombela authored Nov 23, 2023
2 parents b702c7f + bb44252 commit fdc176a
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 65 deletions.
31 changes: 12 additions & 19 deletions BackwardConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@ set(STACK_DETAILS_BFD FALSE CACHE BOOL
set(STACK_DETAILS_DWARF FALSE CACHE BOOL
"Use libdwarf/libelf to read debug info")

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT DEFINED BACKWARD_TESTS)
# If this is a top level CMake project, we most lixely want the tests
set(BACKWARD_TESTS ON CACHE BOOL "Enable tests")
else()
set(BACKWARD_TESTS OFF CACHE BOOL "Enable tests")
endif()
###############################################################################
# CONFIGS
###############################################################################
Expand Down Expand Up @@ -222,7 +216,10 @@ if(WIN32)
endif()
endif()

set(BACKWARD_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}")
set(BACKWARD_INCLUDE_DIR
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

set(BACKWARD_HAS_EXTERNAL_LIBRARIES FALSE)
set(FIND_PACKAGE_REQUIRED_VARS BACKWARD_INCLUDE_DIR)
Expand All @@ -239,6 +236,9 @@ list(APPEND _BACKWARD_INCLUDE_DIRS ${BACKWARD_INCLUDE_DIR})

# add_backward, optional bool argument; if passed and true, backward will be included as a system header
macro(add_backward target)
message(DEPRECATION "The add_backward() macro is deprecated, use target_link_libraries() to link to "
"one of the exported targets: Backward::Interface, Backward::Object, or Backward::Backward."
)
if ("${ARGN}")
target_include_directories(${target} SYSTEM PRIVATE ${BACKWARD_INCLUDE_DIRS})
else()
Expand All @@ -248,7 +248,7 @@ macro(add_backward target)
set_property(TARGET ${target} APPEND PROPERTY LINK_LIBRARIES ${BACKWARD_LIBRARIES})
endmacro()

set(BACKWARD_INCLUDE_DIRS ${_BACKWARD_INCLUDE_DIRS} CACHE INTERNAL "_BACKWARD_INCLUDE_DIRS")
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 All @@ -263,15 +263,8 @@ foreach(var ${BACKWARD_DEFINITIONS})
mark_as_advanced(${var_name})
endforeach()

if (NOT TARGET Backward::Backward)
add_library(Backward::Backward INTERFACE IMPORTED)
set_target_properties(Backward::Backward PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${BACKWARD_INCLUDE_DIRS}"
INTERFACE_COMPILE_DEFINITIONS "${BACKWARD_DEFINITIONS}"
)
if(BACKWARD_HAS_EXTERNAL_LIBRARIES)
set_target_properties(Backward::Backward PROPERTIES
INTERFACE_LINK_LIBRARIES "${BACKWARD_LIBRARIES}"
)
endif()
# if this file is used from the install tree by find_package(), include the
# file CMake-generated file where the targets are defined
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/BackwardTargets.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/BackwardTargets.cmake)
endif()
74 changes: 53 additions & 21 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.12)
project(backward CXX)

# Introduce variables:
Expand All @@ -31,6 +31,22 @@ include(GNUInstallDirs)

include(BackwardConfig.cmake)

###############################################################################
# OPTIONS
###############################################################################

option(BACKWARD_SHARED "Build backward as a shared library" OFF)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT DEFINED BACKWARD_TESTS)
# If this is a top level CMake project, we most lixely want the tests
set(BACKWARD_TESTS ON CACHE BOOL "Enable tests")
else()
set(BACKWARD_TESTS OFF CACHE BOOL "Enable tests")
endif()

###############################################################################
# COMPILER FLAGS
###############################################################################

# check if compiler is nvcc or nvcc_wrapper
set(COMPILER_IS_NVCC false)
get_filename_component(COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME)
Expand All @@ -52,10 +68,6 @@ if (${COMPILER_IS_NVCC})
set(CMAKE_CXX_EXTENSIONS OFF)
endif()

###############################################################################
# COMPILER FLAGS
###############################################################################

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
if (NOT ${COMPILER_IS_NVCC})
Expand All @@ -65,31 +77,42 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_COMPILER_IS_GNUCXX)
endif()

###############################################################################
# BACKWARD OBJECT
# BACKWARD INTERFACE
###############################################################################

add_library(backward_object OBJECT backward.cpp)
target_compile_definitions(backward_object PRIVATE ${BACKWARD_DEFINITIONS})
target_include_directories(backward_object PRIVATE ${BACKWARD_INCLUDE_DIRS})
set(BACKWARD_ENABLE $<TARGET_OBJECTS:backward_object> CACHE STRING
"Link with this object to setup backward automatically")
add_library(backward_interface INTERFACE)
set_target_properties(backward_interface PROPERTIES EXPORT_NAME Interface)
target_compile_definitions(backward_interface INTERFACE ${BACKWARD_DEFINITIONS})
target_include_directories(backward_interface INTERFACE ${BACKWARD_INCLUDE_DIRS})
if(BACKWARD_HAS_EXTERNAL_LIBRARIES)
target_link_libraries(backward_interface INTERFACE ${BACKWARD_LIBRARIES})
endif()
add_library(Backward::Interface ALIAS backward_interface)

###############################################################################
# BACKWARD OBJECT (Includes backward.cpp)
# (Note that this target is not exported, since CMake currently does not allow
# exporting an OBJECT library.)
###############################################################################

add_library(backward_object OBJECT backward.cpp)
set_target_properties(backward_object PROPERTIES EXPORT_NAME Object)
target_link_libraries(backward_object PUBLIC Backward::Interface)
add_library(Backward::Object ALIAS backward_object)

###############################################################################
# BACKWARD LIBRARY (Includes backward.cpp)
# (Note that the linker will not include unused objects from a static library,
# unless the -Wl,--whole-archive option (or similar) is used.)
###############################################################################
option(BACKWARD_SHARED "Build dynamic backward-cpp shared lib" OFF)

set(libtype STATIC)
if(BACKWARD_SHARED)
set(libtype SHARED)
endif()
add_library(backward ${libtype} backward.cpp)
target_compile_definitions(backward PUBLIC ${BACKWARD_DEFINITIONS})
target_include_directories(backward PUBLIC ${BACKWARD_INCLUDE_DIRS})
if(BACKWARD_HAS_EXTERNAL_LIBRARIES)
set_target_properties(backward PROPERTIES
INTERFACE_LINK_LIBRARIES "${BACKWARD_LIBRARIES}")
endif()
set_target_properties(backward PROPERTIES EXPORT_NAME Backward)
target_link_libraries(backward PUBLIC Backward::Interface)
add_library(Backward::Backward ALIAS backward)

###############################################################################
Expand All @@ -107,7 +130,7 @@ if(BACKWARD_TESTS)

add_executable(${test_name} ${src} ${ARGN} $<TARGET_OBJECTS:test_main>)

target_link_libraries(${test_name} PRIVATE Backward::Backward)
target_link_libraries(${test_name} PRIVATE Backward::Interface)

add_test(NAME ${name} COMMAND ${test_name})
endmacro()
Expand All @@ -130,7 +153,7 @@ if(BACKWARD_TESTS)
)

foreach(test ${TESTS})
backward_add_test(test/${test}.cpp ${BACKWARD_ENABLE})
backward_add_test(test/${test}.cpp backward.cpp)
endforeach()
endif()

Expand All @@ -140,5 +163,14 @@ install(
)
install(
FILES "BackwardConfig.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/backward
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
# check if Backward is being used as a top-level project or included as a subproject
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
# export the targets (note that exporting backward_object does not make sense)
install(TARGETS backward_interface backward EXPORT BackwardTargets)
# install a CMake file for the exported targets
install(EXPORT BackwardTargets
NAMESPACE Backward::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
endif()
60 changes: 35 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,26 @@ Note for [folly](https://github.com/facebook/folly) library users: must define `

### Integration with CMake

If you are using CMake and want to use its configuration abilities to save
you the trouble, you can easily integrate Backward, depending on how you obtained
If you are using CMake and want to use its configuration abilities to save you
the trouble, you can easily integrate Backward, depending on how you obtained
the library.

Notice that all approaches are equivalent in the way Backward is added to a
CMake target, the difference is in how CMake is pointed to the Backward
sources. Backward defines three targets:

- `Backward::Interface` is an interface target that brings compiler definition
flags, include directory, and external libraries. This is all you need to use
the `backward.hpp` header library.
- `Backward::Object` brings `Backward::Interface` and `backward.cpp` as an
`OBJECT` CMake library. This target cannot be exported, so it is not
available when Backward is used via `find_package`.
- `Backward::Backward` brings `Backward::Interface` and `backward.cpp` as
either `STATIC` or `SHARED` library (depending on the `BACKWARD_SHARED`
option). This target is exported and always available, however note that the
linker will not include unused objects from a static library, unless the
`-Wl,--whole-archive` option (or similar) is used.

#### With `FetchContent()`:

If you are using a recent version of CMake, you can integrate `backward` via `FetchContent` like below:
Expand All @@ -58,47 +74,41 @@ include(FetchContent)
# Also requires one of: libbfd (gnu binutils), libdwarf, libdw (elfutils)
FetchContent_Declare(backward
GIT_REPOSITORY https://github.com/bombela/backward-cpp
GIT_TAG v1.6)
GIT_REPOSITORY https://github.com/bombela/backward-cpp
GIT_TAG master # or a version tag, such as v1.6
SYSTEM # optional, the Backward include directory will be treated as system directory
)
FetchContent_MakeAvailable(backward)
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS src/*.cpp)
add_executable(example ${SOURCES} ${BACKWARD_ENABLE}) # Notice the "BACKWARD_ENABLE" here
add_backward(example)
# Add Backward to your target (either Backward::Interface, Backward::Object, or Backward::Backward)
target_link_libraries(mytarget PUBLIC Backward::Interface)
```

#### As a subdirectory:

In this case you have a subdirectory containing the whole repository of Backward
(eg.: using git-submodules), in this case you can do:
(e.g. using [git-submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules)),
in this case you can do:

```
```cmake
add_subdirectory(/path/to/backward-cpp)
# This will add backward.cpp to your target
add_executable(mytarget mysource.cpp ${BACKWARD_ENABLE})
# This will add libraries, definitions and include directories needed by backward
# by setting each property on the target.
add_backward(mytarget)
# Add Backward to your target (either Backward::Interface, Backward::Object, or Backward::Backward)
target_link_libraries(mytarget PUBLIC Backward::Interface)
```

#### Modifying CMAKE_MODULE_PATH
#### Modifying `CMAKE_MODULE_PATH`:

In this case you can have Backward installed as a subdirectory:

```
list(APPEND CMAKE_MODULE_PATH /path/to/backward-cpp)
find_package(Backward)
# This will add libraries, definitions and include directories needed by backward
# through an IMPORTED target.
target_link_libraries(mytarget PUBLIC Backward::Backward)
# Add Backward to your target (either Backward::Interface or Backward::Backward)
target_link_libraries(mytarget PUBLIC Backward::Interface)
```

Notice that this is equivalent to using the the approach that uses `add_subdirectory()`,
however it uses cmake's [imported target](https://cmake.org/Wiki/CMake/Tutorials/Exporting_and_Importing_Targets) mechanism.

#### Installation through a regular package manager

In this case you have obtained Backward through a package manager.
Expand All @@ -109,10 +119,10 @@ Packages currently available:
```
find_package(Backward)
# This will add libraries, definitions and include directories needed by backward
# through an IMPORTED target.
target_link_libraries(mytarget PUBLIC Backward::Backward)
# Add Backward to your target (either Backward::Interface or Backward::Backward)
target_link_libraries(mytarget PUBLIC Backward::Interface)
```

### Libraries to unwind the stack

On Linux and macOS, backtrace can back-trace or "walk" the stack using the
Expand Down

0 comments on commit fdc176a

Please sign in to comment.