diff --git a/packages/react-native/ReactAndroid/build.gradle.kts b/packages/react-native/ReactAndroid/build.gradle.kts index 45b852e10c88..10668a9ec24b 100644 --- a/packages/react-native/ReactAndroid/build.gradle.kts +++ b/packages/react-native/ReactAndroid/build.gradle.kts @@ -238,6 +238,10 @@ val preparePrefab by "../ReactCommon/react/renderer/runtimescheduler/", "react/renderer/runtimescheduler/", ), + Pair( + "../ReactCommon/react/renderer/runtimescheduler/React/", + "React/", + ), Pair("../ReactCommon/react/renderer/scheduler/", "react/renderer/scheduler/"), Pair("../ReactCommon/react/renderer/telemetry/", "react/renderer/telemetry/"), Pair("../ReactCommon/react/renderer/uimanager/", "react/renderer/uimanager/"), diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/CMakeLists.txt index 30d11bacb3a8..2d19f91d98b4 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/CMakeLists.txt @@ -13,6 +13,18 @@ add_library(react_renderer_runtimescheduler STATIC ${react_renderer_runtimesched target_include_directories(react_renderer_runtimescheduler PUBLIC ${REACT_COMMON_DIR}) +# POC: vend the umbrella as . The umbrella physically +# lives at this module's `React/` subdir, so adding the module dir as a public +# include dir makes `` resolve for dependents. +# NOTE (macOS, case-insensitive FS): the `React/` prefix differs from the +# existing lowercase `react/` tree only by case. They do not collide here (the +# two RuntimeScheduler.h files sit at different depths), but this is a known +# case-insensitive-FS fragility tracked in +# __docs__/RuntimeSchedulerUmbrellaPOC.fb.md. +# NOTE: adding the module dir also exposes the other headers as bare includes; a +# real rollout would scope this to a dedicated public-include subdir. +target_include_directories(react_renderer_runtimescheduler PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + target_link_libraries(react_renderer_runtimescheduler callinvoker jsi @@ -27,3 +39,20 @@ target_link_libraries(react_renderer_runtimescheduler jsinspector_tracing) target_compile_reactnative_options(react_renderer_runtimescheduler PRIVATE) target_compile_options(react_renderer_runtimescheduler PRIVATE -Wpedantic) + +# POC (public C++ API surface reduction): this module exposes a single public +# umbrella header, vended top-level as . +# Including any other module header directly is gated by an opt-in guard +# (RuntimeSchedulerUmbrellaGuard.h) that is inert unless +# REACT_RUNTIMESCHEDULER_ENFORCE_UMBRELLA is defined. +# +# Unlike Buck, CMake exposes the whole include directory, so the individual +# headers (and the private RuntimeScheduler_Modern.h / RuntimeScheduler_Legacy.h) +# remain physically includable here. The only way to enforce "umbrella only" in +# the OSS build is the guard macro. To enable it, uncomment the block below. +# NOTE: this breaks any consumer that still includes the individual headers +# directly, so only enable it after migrating consumers to the umbrella. +# +# target_compile_definitions(react_renderer_runtimescheduler +# PRIVATE REACT_RUNTIMESCHEDULER_BUILDING # this library's own .cpp may include the headers directly +# PUBLIC REACT_RUNTIMESCHEDULER_ENFORCE_UMBRELLA) # consumers must go through the umbrella diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React-runtimescheduler.podspec b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React-runtimescheduler.podspec index 56823e61d623..c63af25cc998 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React-runtimescheduler.podspec +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React-runtimescheduler.podspec @@ -33,9 +33,24 @@ Pod::Spec.new do |s| s.source = source s.source_files = podspec_sources("**/*.{cpp,h}", "**/*.h") s.header_dir = "react/renderer/runtimescheduler" - s.exclude_files = "tests" + # The umbrella is vended top-level as via the + # "Umbrella" subspec below, so exclude it from the main (react/...) mapping. + s.exclude_files = ["tests", "React"] + # POC (public C++ API surface reduction): RuntimeScheduler exposes a single + # public umbrella header, vended top-level as . + # Including any other module header directly is gated by an opt-in guard that is inert unless + # REACT_RUNTIMESCHEDULER_ENFORCE_UMBRELLA is defined. CocoaPods exposes the + # whole header_dir, so the individual headers remain includable here; the guard + # macro is the only way to enforce "umbrella only" in the pods build. + # + # To enable enforcement: add REACT_RUNTIMESCHEDULER_BUILDING=1 to this pod's own + # compilation via the GCC_PREPROCESSOR_DEFINITIONS line below, and propagate + # REACT_RUNTIMESCHEDULER_ENFORCE_UMBRELLA to consumers. NOTE: enforcing on + # consumers needs `user_target_xcconfig`, which CocoaPods discourages (xcconfig + # collisions), and it breaks consumers that still include the headers directly. s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), + # "GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) REACT_RUNTIMESCHEDULER_BUILDING=1", "HEADER_SEARCH_PATHS" => header_search_paths.join(' ')} resolve_use_frameworks(s, header_mappings_dir: "../../..", module_name: "React_runtimescheduler") @@ -56,4 +71,22 @@ Pod::Spec.new do |s| depend_on_js_engine(s) add_rn_third_party_dependencies(s) add_rncore_dependency(s) + + # POC: vend the umbrella under the shared top-level `React/` prefix, i.e. + # `#include `. header_mappings_dir = "React" maps the + # physical react/renderer/runtimescheduler/React/RuntimeScheduler.h to a + # leaf-level RuntimeScheduler.h, and header_dir = "React" places it under React/. + # + # NOTE (untested): CocoaPods cannot be run in the internal build, so the exact + # header_dir / header_mappings_dir interaction needs validation with `pod install`. + # NOTE (macOS): under use_frameworks!, this pod's Headers would contain both + # `React/` (umbrella) and `react/...` (interface headers); on a case-insensitive + # filesystem those fold to one directory. They do not overwrite (different + # depths), but this is a known fragility tracked in + # __docs__/RuntimeSchedulerUmbrellaPOC.fb.md. + s.subspec "Umbrella" do |ss| + ss.source_files = "React/*.h" + ss.header_dir = "React" + ss.header_mappings_dir = "React" + end end diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React/RuntimeScheduler.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React/RuntimeScheduler.h new file mode 100644 index 000000000000..0feee3d247ca --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React/RuntimeScheduler.h @@ -0,0 +1,44 @@ +/* + * 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 `runtimescheduler` module — public entry point. +// +// POC (public C++ API surface reduction). Consumers include ONLY this header, +// via the shared top-level `React/` prefix: +// +// #include +// +// The individual interface headers below are re-exported here. The fork +// implementations `RuntimeScheduler_Modern` / `RuntimeScheduler_Legacy` are +// deliberately NOT included: they are private to the build unit. +// +// The `React/` prefix is a shared namespace (also used by React-Core's Obj-C +// headers). Naming policy: one umbrella per module, named after the module, to +// avoid leaf collisions in the shared namespace. +// +// NOTE: this file lives at `react/renderer/runtimescheduler/React/` so the +// `` include path can be produced physically (CMake) as well as via +// header maps (Buck) and `header_dir` (CocoaPods). RN-internal code should keep +// using the fine-grained `` includes; only +// outside consumers use this umbrella. +// ============================================================================= + +// Mark that subsequent module headers are pulled in through the umbrella. This +// satisfies the per-header umbrella guard (see RuntimeSchedulerUmbrellaGuard.h). +#define REACT_RUNTIMESCHEDULER_UMBRELLA_INCLUDE + +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h index ded6174907f1..3678cf427374 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h index 6e1c2a79c91c..52d5d9d10cd6 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h index 590b27a70480..ce4773c61bb7 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerEventTimingDelegate.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerEventTimingDelegate.h index 5900c33a9f4e..360f97bb8ba1 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerEventTimingDelegate.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerEventTimingDelegate.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerIntersectionObserverDelegate.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerIntersectionObserverDelegate.h index 614aed82e811..f3d9adf94fc1 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerIntersectionObserverDelegate.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerIntersectionObserverDelegate.h @@ -7,6 +7,8 @@ #pragma once +#include + #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerUmbrellaGuard.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerUmbrellaGuard.h new file mode 100644 index 000000000000..117f73f4d421 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerUmbrellaGuard.h @@ -0,0 +1,27 @@ +/* + * 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. + */ + +// POC: This header is intentionally NOT `#pragma once` guarded. It must be +// re-evaluated on every inclusion so that any direct `#include` of a private +// module header is caught. +// +// The runtimescheduler module exposes a single public entry point: +// +// +// All other headers in this module are implementation details. To enforce +// that, define `REACT_RUNTIMESCHEDULER_ENFORCE_UMBRELLA` for the consuming +// build target. When enforcement is on, including any module header other than +// the umbrella (and outside of the module's own build) becomes a hard error. +// +// Enforcement is OPT-IN: when the macro is not defined the guard is inert, so +// existing consumers and the OSS CMake build are unaffected by this POC. + +#if defined(REACT_RUNTIMESCHEDULER_ENFORCE_UMBRELLA) && !defined(REACT_RUNTIMESCHEDULER_UMBRELLA_INCLUDE) && \ + !defined(REACT_RUNTIMESCHEDULER_BUILDING) +#error \ + "Do not include runtimescheduler headers directly. Include instead." +#endif diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/SchedulerPriorityUtils.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/SchedulerPriorityUtils.h index df109665581e..691f26bf83ac 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/SchedulerPriorityUtils.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/SchedulerPriorityUtils.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/Task.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/Task.h index e1a91f57303d..bb3186835e0d 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/Task.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/Task.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/primitives.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/primitives.h index b5e52894ba14..c9f006c9c71b 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/primitives.h @@ -7,6 +7,8 @@ #pragma once +#include + #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp index 574ec8884fcc..dd08990b99e8 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. */ +#include #include #include #include #include #include #include -#include #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/SchedulerPriorityTest.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/SchedulerPriorityTest.cpp index d1807ad81460..bd29f644201d 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/SchedulerPriorityTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/SchedulerPriorityTest.cpp @@ -5,9 +5,8 @@ * LICENSE file in the root directory of this source tree. */ +#include #include -#include -#include #include using namespace facebook::react;