Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- Improve log and metric delivery when telemetry is captured faster than envelopes can be serialized by offloading serialization to an internal thread pool. ([#1946](https://github.com/getsentry/sentry-native/pull/1946))
- Wine: fix OS version detection and cross-compiling Windows builds from Linux. ([#2001](https://github.com/getsentry/sentry-native/pull/2001))
- Destroy condition variables as approriate when no longer needed. ([#2004](https://github.com/getsentry/sentry-native/pull/2004))
- CMake: `pkg-config` is no longer a hard build requirement. `SENTRY_LIBUNWIND_SYSTEM` and `SENTRY_BREAKPAD_SYSTEM` still prefer the `pkg-config` metadata of the system package, but now fall back to `find_library()`/`find_path()` when the tool or the `.pc` file is missing. The same applies to the exported CMake config, which no longer requires consumers of a static build to have `pkg-config` installed.
- Crashpad/Windows: preserve module CodeView UUIDs for minimal PDB70 records with empty PDB filenames. ([#2003](https://github.com/getsentry/sentry-native/pull/2003))

## 0.16.3
Expand Down
23 changes: 12 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ if(WIN32)
endif()

include(cmake/utils.cmake)
include(cmake/sentry-find-system-library.cmake)
if (WIN32 AND SENTRY_BUILD_SHARED_LIBS)
sentry_add_version_resource(sentry "Client Library")
endif()
Expand Down Expand Up @@ -705,12 +706,11 @@ endif()
if(SENTRY_WITH_LIBUNWIND)
if(LINUX)
if(SENTRY_LIBUNWIND_SYSTEM)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBUNWIND REQUIRED IMPORTED_TARGET libunwind)
sentry_find_libunwind()
if(SENTRY_BUILD_SHARED_LIBS)
target_link_libraries(sentry PRIVATE PkgConfig::LIBUNWIND)
target_link_libraries(sentry PRIVATE sentry::libunwind)
else()
target_link_libraries(sentry PUBLIC PkgConfig::LIBUNWIND)
target_link_libraries(sentry PUBLIC sentry::libunwind)
endif()
else()
# Use vendored libunwind
Expand Down Expand Up @@ -802,13 +802,12 @@ elseif(SENTRY_BACKEND_BREAKPAD)
option(SENTRY_BREAKPAD_SYSTEM "Use system breakpad" OFF)
if(SENTRY_BREAKPAD_SYSTEM)
target_compile_definitions(sentry PRIVATE SENTRY_BREAKPAD_SYSTEM)
# system breakpad is using pkg-config, see `external/breakpad/breakpad-client.pc.in`
find_package(PkgConfig REQUIRED)
pkg_check_modules(BREAKPAD REQUIRED IMPORTED_TARGET breakpad-client)
# system breakpad ships pkg-config metadata, see `external/breakpad/breakpad-client.pc.in`
sentry_find_breakpad_client()
if(SENTRY_BUILD_SHARED_LIBS)
target_link_libraries(sentry PRIVATE PkgConfig::BREAKPAD)
target_link_libraries(sentry PRIVATE sentry::breakpad-client)
else()
target_link_libraries(sentry PUBLIC PkgConfig::BREAKPAD)
target_link_libraries(sentry PUBLIC sentry::breakpad-client)
endif()
else()
add_subdirectory(external)
Expand Down Expand Up @@ -934,8 +933,8 @@ elseif(SENTRY_BACKEND_NATIVE)

if(SENTRY_WITH_LIBUNWIND AND LINUX)
if(SENTRY_LIBUNWIND_SYSTEM)
pkg_check_modules(LIBUNWIND_PTRACE REQUIRED IMPORTED_TARGET libunwind-ptrace)
target_link_libraries(sentry-crash PRIVATE PkgConfig::LIBUNWIND PkgConfig::LIBUNWIND_PTRACE)
sentry_find_libunwind_ptrace()
target_link_libraries(sentry-crash PRIVATE sentry::libunwind sentry::libunwind-ptrace)
else()
# Use unwind_remote for the daemon (includes ptrace accessors
# for remote DWARF unwinding of the crashed process)
Expand Down Expand Up @@ -1018,6 +1017,8 @@ sentry_install(
FILES
"${PROJECT_BINARY_DIR}/sentry-config.cmake"
"${PROJECT_BINARY_DIR}/sentry-config-version.cmake"
# `sentry-config.cmake` recreates the system-library targets for consumers of a static build
"${SENTRY_SOURCE_DIR}/cmake/sentry-find-system-library.cmake"
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}")
if(WIN32 AND MSVC AND SENTRY_BUILD_SHARED_LIBS)
sentry_install(FILES $<TARGET_PDB_FILE:sentry>
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,15 +266,20 @@ using `cmake -D BUILD_SHARED_LIBS=OFF ..`.
This instructs the build system to use system-installed breakpad libraries instead of the in-tree version.

- `SENTRY_LIBUNWIND_SYSTEM` (Default: `OFF`, only for Linux):
This instructs the build system to use a system-installed `libunwind` (found via `pkg-config`) instead of the
vendored copy in `vendor/libunwind`.
This instructs the build system to use a system-installed `libunwind` instead of the vendored copy in
`vendor/libunwind`.

In contrast to the vendored `libunwind` which is always built as a static archive and either linked into the
resulting shared library or colocated with the other static artifacts, with `SENTRY_LIBUNWIND_SYSTEM=ON`, the library
type (shared or static) is determined by the host distribution's package. The `SENTRY_BUILD_SHARED_LIBS` option only
controls how the dependency is exposed to consuming CMake projects, not the library type of the system `libunwind`
itself. Ensure matching build and target environments when using system packages.

Both `SENTRY_BREAKPAD_SYSTEM` and `SENTRY_LIBUNWIND_SYSTEM` read the `pkg-config` metadata of the system package
when `pkg-config`/`pkgconf` is installed, and fall back to CMake's own `find_library()`/`find_path()` lookup when it
is not, so `pkg-config` is a convenience rather than a build requirement for either option. The only remaining
build-time user of `pkg-config` is the vendored `crashpad`, and only on Linux with `CRASHPAD_ENABLE_STACKTRACE=ON`.

- `SENTRY_TRANSPORT_COMPRESSION` (Default: `OFF`):
Adds Gzip transport compression. Requires `zlib`.

Expand Down
104 changes: 104 additions & 0 deletions cmake/sentry-find-system-library.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Locates a system library the way CMake's own find modules do: `pkg-config` supplies search hints
# when it happens to be installed, and `find_library()`/`find_path()` do the actual lookup either way.
# See `FindLibinput`, `FindFontconfig` and the other bundled modules that follow the same shape.
#
# The only places sentry-native consults `pkg-config` are the optional `SENTRY_LIBUNWIND_SYSTEM` and
# `SENTRY_BREAKPAD_SYSTEM` code paths, and only on Linux. Requesting it with
# `find_package(PkgConfig REQUIRED)` nevertheless turned the tool into a hard build requirement for
# anyone packaging sentry-native, which is why package managers end up declaring it on every platform,
# including those where it is never invoked.
#
# Defines the imported target `TARGET` on success, and fails through
# `find_package_handle_standard_args()` with the usual "could not find" diagnostic otherwise.
#
# sentry_find_system_library(<Name>
# TARGET <target>
# PKG_CONFIG_MODULE <module>
# LIBRARY_NAMES <name>...
# [HEADER_NAMES <header>...]
# [HEADER_PATH_SUFFIXES <suffix>...])
function(sentry_find_system_library NAME)
cmake_parse_arguments(SFSL "" "TARGET;PKG_CONFIG_MODULE"
"LIBRARY_NAMES;HEADER_NAMES;HEADER_PATH_SUFFIXES" ${ARGN})

if(TARGET "${SFSL_TARGET}")
return()
endif()

# Hints only. A missing tool or a missing `.pc` file just leaves the hints empty. The guard is
# needed because `pkg_check_modules()` is defined by `FindPkgConfig` itself, so it does not exist
# when that module was never loaded.
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_${NAME} QUIET "${SFSL_PKG_CONFIG_MODULE}")
endif()

set(libraries "")
set(required_vars "")
foreach(library_name IN LISTS SFSL_LIBRARY_NAMES)
string(MAKE_C_IDENTIFIER "${NAME}_${library_name}_LIBRARY" cache_var)
find_library("${cache_var}" NAMES "${library_name}" HINTS ${PC_${NAME}_LIBRARY_DIRS})
mark_as_advanced("${cache_var}")
list(APPEND libraries "${${cache_var}}")
list(APPEND required_vars "${cache_var}")
endforeach()

if(SFSL_HEADER_NAMES)
find_path(${NAME}_INCLUDE_DIR
NAMES ${SFSL_HEADER_NAMES}
HINTS ${PC_${NAME}_INCLUDE_DIRS}
PATH_SUFFIXES ${SFSL_HEADER_PATH_SUFFIXES})
mark_as_advanced(${NAME}_INCLUDE_DIR)
list(APPEND required_vars ${NAME}_INCLUDE_DIR)
endif()

# These lookups only run once the user has opted into a system library, so a miss is fatal.
# `find_package_handle_standard_args()` reads this to pick the failure mode and the message.
set(${NAME}_FIND_REQUIRED TRUE)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(${NAME} REQUIRED_VARS ${required_vars})

add_library("${SFSL_TARGET}" INTERFACE IMPORTED)
set_target_properties("${SFSL_TARGET}" PROPERTIES INTERFACE_LINK_LIBRARIES "${libraries}")
if(${NAME}_INCLUDE_DIR)
set_target_properties("${SFSL_TARGET}" PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${${NAME}_INCLUDE_DIR}")
endif()
if(PC_${NAME}_CFLAGS_OTHER)
set_target_properties("${SFSL_TARGET}" PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_${NAME}_CFLAGS_OTHER}")
endif()
endfunction()

# The lookups below are shared between the build itself and the installed `sentry-config.cmake`, which
# has to recreate the same imported targets for consumers of a static sentry-native. Keeping them here
# means the two cannot drift.

function(sentry_find_libunwind)
sentry_find_system_library(SentryLibunwind
TARGET sentry::libunwind
PKG_CONFIG_MODULE libunwind
LIBRARY_NAMES unwind
HEADER_NAMES libunwind.h)
endfunction()

function(sentry_find_libunwind_ptrace)
# `libunwind-ptrace.pc` declares `Requires: libunwind-generic libunwind`; the generic half has to
# be named here, and callers link `sentry::libunwind` alongside for the other.
sentry_find_system_library(SentryLibunwindPtrace
TARGET sentry::libunwind-ptrace
PKG_CONFIG_MODULE libunwind-ptrace
LIBRARY_NAMES unwind-ptrace unwind-generic
HEADER_NAMES libunwind-ptrace.h)
endfunction()

function(sentry_find_breakpad_client)
# `breakpad-client.pc` exposes the headers below `${includedir}/breakpad`, matching the
# `client/<os>/...` includes in `src/backends/sentry_backend_breakpad.cpp`.
sentry_find_system_library(SentryBreakpadClient
TARGET sentry::breakpad-client
PKG_CONFIG_MODULE breakpad-client
LIBRARY_NAMES breakpad_client
HEADER_NAMES google_breakpad/common/breakpad_types.h
HEADER_PATH_SUFFIXES breakpad)
endfunction()
7 changes: 3 additions & 4 deletions sentry-config.cmake.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
include("${CMAKE_CURRENT_LIST_DIR}/sentry-find-system-library.cmake")

set(SENTRY_BACKEND @SENTRY_BACKEND@)
set(SENTRY_TRANSPORT @SENTRY_TRANSPORT@)
Expand All @@ -16,12 +17,10 @@ if(NOT SENTRY_BUILD_SHARED_LIBS)
find_dependency(ZLIB)
endif()
if(SENTRY_BACKEND STREQUAL "breakpad" AND SENTRY_BREAKPAD_SYSTEM)
find_dependency(PkgConfig)
pkg_check_modules(BREAKPAD REQUIRED IMPORTED_TARGET breakpad-client)
sentry_find_breakpad_client()
endif()
if(SENTRY_LIBUNWIND_SYSTEM)
find_dependency(PkgConfig)
pkg_check_modules(LIBUNWIND REQUIRED IMPORTED_TARGET libunwind)
sentry_find_libunwind()
endif()
if(SENTRY_TRANSPORT STREQUAL "curl" AND NOT SENTRY_LINK_CURL STREQUAL "OFF")
find_dependency(CURL)
Expand Down