From 8bd5860490dd8d0f5e0e2abe9c362a6da0914e0d Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Fri, 11 Sep 2026 05:29:24 -0700 Subject: [PATCH] Cover react/renderer/debug with Stable API guards (#58183) Summary: Classifies `react/renderer/debug:debug` as a public target under the three-tier C++ stable API visibility model, and adds the module umbrella `` as its public entry point. Consumers that opt into `RN_STRICT_API` now get an error if they include the module's headers directly and have to go through the umbrella instead; without that flag the guards are inert, so no existing build changes behaviour. The pod's source glob is narrowed to the module's own directory so the umbrella is not also flattened into `react/renderer/debug`, and the matching `headers-config.js` exception splits the pod into module and umbrella subspecs so `` resolves in the SwiftPM prebuild. Changelog: [Internal] Differential Revision: D117850084 --- .../ReactAndroid/build.gradle.kts | 1 + .../react/renderer/debug/CMakeLists.txt | 3 +- .../renderer/debug/DebugStringConvertible.h | 2 ++ .../debug/DebugStringConvertibleItem.h | 2 ++ .../debug/React-rendererdebug.podspec | 11 ++++-- .../renderer/debug/React/RendererDebug.h | 35 +++++++++++++++++++ .../debug/debugStringConvertibleUtils.h | 2 ++ .../ReactCommon/react/renderer/debug/flags.h | 2 ++ .../scripts/ios-prebuild/headers-config.js | 17 +++++++++ 9 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 packages/react-native/ReactCommon/react/renderer/debug/React/RendererDebug.h diff --git a/packages/react-native/ReactAndroid/build.gradle.kts b/packages/react-native/ReactAndroid/build.gradle.kts index 8a27e3e4f470..1b30c9275263 100644 --- a/packages/react-native/ReactAndroid/build.gradle.kts +++ b/packages/react-native/ReactAndroid/build.gradle.kts @@ -149,6 +149,7 @@ val preparePrefab by Pair("../ReactCommon/react/debug/React/", "React/"), // react_renderer_debug Pair("../ReactCommon/react/renderer/debug/", "react/renderer/debug/"), + Pair("../ReactCommon/react/renderer/debug/React/", "React/"), // react_renderer_graphics Pair("../ReactCommon/react/renderer/graphics/", "react/renderer/graphics/"), Pair("../ReactCommon/react/renderer/graphics/platform/android/", ""), diff --git a/packages/react-native/ReactCommon/react/renderer/debug/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/debug/CMakeLists.txt index a1fccffe2bf8..572b0c911d68 100644 --- a/packages/react-native/ReactCommon/react/renderer/debug/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/debug/CMakeLists.txt @@ -12,7 +12,8 @@ file(GLOB react_renderer_debug_SRC CONFIGURE_DEPENDS *.cpp) add_library(react_renderer_debug OBJECT ${react_renderer_debug_SRC}) target_include_directories(react_renderer_debug PUBLIC ${REACT_COMMON_DIR}) -target_link_libraries(react_renderer_debug folly_runtime react_debug) +target_include_directories(react_renderer_debug INTERFACE ${REACT_COMMON_DIR}/react/renderer/debug) +target_link_libraries(react_renderer_debug folly_runtime react_cxxstableapi react_debug) target_compile_reactnative_options(react_renderer_debug PRIVATE) target_compile_options(react_renderer_debug PRIVATE -Wpedantic) diff --git a/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertible.h b/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertible.h index 726531a2837e..e298aa11d57f 100644 --- a/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertible.h +++ b/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertible.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertibleItem.h b/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertibleItem.h index dd9e79039595..ad3d261a3a6e 100644 --- a/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertibleItem.h +++ b/packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertibleItem.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/debug/React-rendererdebug.podspec b/packages/react-native/ReactCommon/react/renderer/debug/React-rendererdebug.podspec index d53f4077d6c5..7bfa97ef639b 100644 --- a/packages/react-native/ReactCommon/react/renderer/debug/React-rendererdebug.podspec +++ b/packages/react-native/ReactCommon/react/renderer/debug/React-rendererdebug.podspec @@ -31,9 +31,8 @@ Pod::Spec.new do |s| s.author = "Meta Platforms, Inc. and its affiliates" s.platforms = min_supported_versions s.source = source - s.source_files = podspec_sources("**/*.{cpp,h,mm}", "**/*.h") + s.source_files = podspec_sources("*.{cpp,h,mm}", "*.h") s.header_dir = "react/renderer/debug" - s.exclude_files = "tests" s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), @@ -46,5 +45,13 @@ Pod::Spec.new do |s| add_rn_third_party_dependencies(s) add_rncore_dependency(s) + s.dependency "React-cxxstableapi" + + s.subspec "debugUmbrella" do |ss| + ss.source_files = "React/*.h" + ss.header_dir = "" + ss.header_mappings_dir = "." + end + mark_as_react_native_build(s) end diff --git a/packages/react-native/ReactCommon/react/renderer/debug/React/RendererDebug.h b/packages/react-native/ReactCommon/react/renderer/debug/React/RendererDebug.h new file mode 100644 index 000000000000..d259573f54bf --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/debug/React/RendererDebug.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +// ============================================================================= +// Umbrella header for the `react/renderer/debug` module - public entry point. +// +// #include +// +// Re-exports the module's public interface headers. React Native's own code +// should keep using the fine-grained `` includes; +// only outside consumers use this umbrella. +// ============================================================================= + +// Marks that the following headers are pulled in through the umbrella, so their +// shared guard () accepts them. The marker +// is saved and restored rather than defined and undefined: the scope ends at +// this block, so later *direct* includes in the same TU are still caught, and +// it nests inside an enclosing umbrella rather than disarming it. +#pragma push_macro("RN_UMBRELLA_CONTEXT") +#undef RN_UMBRELLA_CONTEXT +#define RN_UMBRELLA_CONTEXT 1 + +#include +#include +#include +#include + +#undef RN_UMBRELLA_CONTEXT +#pragma pop_macro("RN_UMBRELLA_CONTEXT") diff --git a/packages/react-native/ReactCommon/react/renderer/debug/debugStringConvertibleUtils.h b/packages/react-native/ReactCommon/react/renderer/debug/debugStringConvertibleUtils.h index 1270f181360c..acc9a23fd84f 100644 --- a/packages/react-native/ReactCommon/react/renderer/debug/debugStringConvertibleUtils.h +++ b/packages/react-native/ReactCommon/react/renderer/debug/debugStringConvertibleUtils.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/debug/flags.h b/packages/react-native/ReactCommon/react/renderer/debug/flags.h index 4fd6f16eaaa0..34c1264dae07 100644 --- a/packages/react-native/ReactCommon/react/renderer/debug/flags.h +++ b/packages/react-native/ReactCommon/react/renderer/debug/flags.h @@ -7,6 +7,8 @@ #pragma once +#include + #include // diff --git a/packages/react-native/scripts/ios-prebuild/headers-config.js b/packages/react-native/scripts/ios-prebuild/headers-config.js index f61e1de8bbef..ca725cf1568d 100644 --- a/packages/react-native/scripts/ios-prebuild/headers-config.js +++ b/packages/react-native/scripts/ios-prebuild/headers-config.js @@ -653,6 +653,23 @@ const PodspecExceptions /*: {[key: string]: PodSpecConfiguration} */ = { }, ], }, + 'ReactCommon/react/renderer/debug/React-rendererdebug.podspec': { + name: 'React-rendererdebug', + headerPatterns: [], + headerDir: '', + subSpecs: [ + { + name: 'debug', + headerPatterns: ['*.h'], + headerDir: 'react/renderer/debug', + }, + { + name: 'debugUmbrella', + headerPatterns: ['React/*.h'], + headerDir: 'React', + }, + ], + }, }; module.exports = {PodspecExceptions};