UNPKG

@sentry/react-native

Version:
114 lines (104 loc) 5.43 kB
# Copyright (c) Sentry. All rights reserved. # # Builds `libsentry-tm-perf-logger.so`, the Sentry-owned shared library that # installs a `facebook::react::NativeModulePerfLogger` into React Native at # JNI load time. # # This CMake target is wired up only when the consuming app is built with # React Native's New Architecture (the only mode where `TurboModulePerfLogger` # exists). The gradle script in `build.gradle` enables `externalNativeBuild` # and `buildFeatures { prefab true }` exclusively when `newArchEnabled` is # set, so this file is never invoked under Old Arch. The file lives under # `src/main/jni/` (rather than the module root) so AGP's CMakeLists # auto-detection cannot pick it up on Old Arch builds where the gradle # `externalNativeBuild` block is intentionally absent — a stray # auto-detection there would attempt to link against `ReactAndroid::reactnative`, # which only ships in the New Architecture prefab AAR. cmake_minimum_required(VERSION 3.13) project(sentry-tm-perf-logger CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Build the shared library from the shared C++ source (also compiled into # `RNSentry.framework` on iOS) plus the Android-specific JNI hook. Paths # are relative to this file: `<module>/src/main/jni/`. add_library( sentry-tm-perf-logger SHARED ${CMAKE_CURRENT_SOURCE_DIR}/../../../../cpp/SentryTurboModulePerfLogger.cpp ${CMAKE_CURRENT_SOURCE_DIR}/OnLoad.cpp ) target_include_directories( sentry-tm-perf-logger PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../../../cpp # ReactAndroid's prefab exposes <ReactCommon/TurboModulePerfLogger.h> # but not the <reactperflogger/NativeModulePerfLogger.h> it # transitively pulls in. Add the source tree's reactperflogger dir to # plug the gap. `REACT_NATIVE_DIR` is provided by `build.gradle`. ${REACT_NATIVE_DIR}/ReactCommon/reactperflogger ) # `RCT_NEW_ARCH_ENABLED` is the same flag the iOS side checks; the # implementation in `SentryTurboModulePerfLogger.cpp` keys off it (combined # with `__ANDROID__`) to decide whether to compile the real install path. target_compile_definitions( sentry-tm-perf-logger PRIVATE RCT_NEW_ARCH_ENABLED=1 ) # Link against React Native's prefab. `reactnative` carries the C++ TurboModule # infrastructure including `facebook::react::TurboModulePerfLogger`'s # `enableLogging` entry point and the `NativeModulePerfLogger` base class # header path. find_package(ReactAndroid REQUIRED CONFIG) target_link_libraries( sentry-tm-perf-logger PRIVATE ReactAndroid::reactnative ) # Force 16 KB ELF LOAD-segment alignment. The NDK linker only defaults to a # 16 KB `max-page-size` from r28 onwards; RN 0.86 / Expo SDK 57 still build # with NDK 27, whose default is 4 KB. Every other `.so` bundled by RN/AGP is # already 16 KB aligned, so without this flag `libsentry-tm-perf-logger.so` # is the lone misaligned library and trips Android 15+'s 16 KB page-size # compatibility check (and Google Play's 16 KB requirement) for the whole # app — even for hosts that never opt in to `enableTurboModuleTracking`, # since the library is packaged whenever the New Architecture is enabled. # On NDK r28+ this option is a redundant no-op. # https://github.com/getsentry/sentry-react-native/issues/6394 target_link_options( sentry-tm-perf-logger PRIVATE "-Wl,-z,max-page-size=16384" ) # Do not fail the link when `facebook::react::TurboModulePerfLogger::enableLogging` # (and friends) cannot be resolved at link time. Those symbols live in React # Native's `reactnative` prefab, which we link above, and they are present in # every ABI's `libreactnative.so`. However, some New Architecture build setups # (e.g. Expo builds on certain ABIs such as armeabi-v7a) do not end up # satisfying the reference at link time, and the NDK/AGP toolchain links with # `-Wl,-z,defs` (a.k.a. `--no-undefined`), which turns that into a fatal # `undefined symbol` error and breaks the whole Android build — even for hosts # that never opt in to `enableTurboModuleTracking`, since the library is # compiled whenever the New Architecture is enabled. # # `-Wl,-z,undefs` (appended after the toolchain's flags, so it wins) makes # undefined symbols non-fatal, leaving them to be resolved at load time against # the already-loaded `libreactnative.so`. This is safe: the library is loaded # lazily and only when tracking is opted in (see RNSentryTurboModulePerfTracker), # and a genuinely unresolvable symbol surfaces as an `UnsatisfiedLinkError` from # `System.loadLibrary` that the Java side already swallows, degrading the # experimental feature to a no-op rather than crashing. When the prefab does # satisfy the reference at link time (the common case) this flag changes nothing. # https://github.com/getsentry/sentry-react-native/issues/6398 target_link_options( sentry-tm-perf-logger PRIVATE "-Wl,-z,undefs" ) # Note: we deliberately do NOT pass `-Wl,--strip-all` (or similar) here. # Android Gradle Plugin's `StripDebugSymbolsTask` already strips the .so for # the packaged APK while preserving the unstripped artefact under # `intermediates/merged_native_libs/.../obj`, which the Sentry Gradle plugin # uploads for crash symbolication. Stripping at link time would erase DWARF # before AGP can copy it, leaving any crash inside this library # unsymbolicated in production.