From d9bdd8f87b7901acc67acd7c5f7e471fdab1bfff Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Tue, 15 Sep 2026 01:20:04 -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 | 39 +++++++++++++++++++ .../debug/debugStringConvertibleUtils.h | 2 + .../ReactCommon/react/renderer/debug/flags.h | 2 + .../scripts/ios-prebuild/headers-config.js | 17 ++++++++ 9 files changed, 76 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 e96e9c258081..f360edaadbf0 100644 --- a/packages/react-native/ReactAndroid/build.gradle.kts +++ b/packages/react-native/ReactAndroid/build.gradle.kts @@ -150,6 +150,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..7780c7af94ba --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/debug/React/RendererDebug.h @@ -0,0 +1,39 @@ +/* + * 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, +// except in headers it exports to consumers: those are preprocessed in the +// consumer's translation unit, where the fine-grained include hits this +// module's . `RN_ALLOW_FRAMEWORKS` does not +// suppress that guard, so a "for frameworks" header must reach this module +// through the 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 31aa70ef825e..5dfa6c0e4443 100644 --- a/packages/react-native/scripts/ios-prebuild/headers-config.js +++ b/packages/react-native/scripts/ios-prebuild/headers-config.js @@ -688,6 +688,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};