Skip to content

Commit 6d3ebea

Browse files
coadometa-codesync[bot]
authored andcommitted
Add cxxstableapi module (#57319)
Summary: Pull Request resolved: #57319 Adds `cxxstableapi` module containing umbrella public, private and for frameworks guards to be used in the C++ stable API. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D108422344 fbshipit-source-id: ffcf468c7dd266893b330c20786ba793b5cb1a05
1 parent fa371d1 commit 6d3ebea

8 files changed

Lines changed: 177 additions & 0 deletions

File tree

packages/react-native/ReactAndroid/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ val preparePrefab by
242242
Pair("../ReactCommon/react/renderer/telemetry/", "react/renderer/telemetry/"),
243243
Pair("../ReactCommon/react/renderer/uimanager/", "react/renderer/uimanager/"),
244244
Pair("../ReactCommon/react/debug/", "react/debug/"),
245+
Pair("../ReactCommon/react/cxxstableapi/", "react/cxxstableapi/"),
245246
Pair("../ReactCommon/react/utils/", "react/utils/"),
246247
Pair("src/main/jni/react/jni", "react/jni/"),
247248
// react_cxxreactpackage

packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ add_react_common_subdir(jsinspector-modern/network)
7575
add_react_common_subdir(jsinspector-modern/tracing)
7676
add_react_common_subdir(hermes/executor)
7777
add_react_common_subdir(hermes/inspector-modern)
78+
add_react_common_subdir(react/cxxstableapi)
7879
add_react_common_subdir(react/renderer/runtimescheduler)
7980
add_react_common_subdir(react/debug)
8081
add_react_common_subdir(react/featureflags)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
#
3+
# This source code is licensed under the MIT license found in the
4+
# LICENSE file in the root directory of this source tree.
5+
6+
cmake_minimum_required(VERSION 3.13)
7+
set(CMAKE_VERBOSE_MAKEFILE on)
8+
9+
include(${REACT_COMMON_DIR}/cmake-utils/react-native-flags.cmake)
10+
11+
# Header-only: the cxxstableapi guards are pure preprocessor headers, so this is
12+
# an INTERFACE library. Headers resolve as <react/cxxstableapi/*.h> via the
13+
# shared ${REACT_COMMON_DIR} include root.
14+
add_library(react_cxxstableapi INTERFACE)
15+
16+
target_include_directories(react_cxxstableapi INTERFACE ${REACT_COMMON_DIR})
17+
target_compile_reactnative_options(react_cxxstableapi INTERFACE)
18+
target_compile_options(react_cxxstableapi INTERFACE -Wpedantic)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
// =============================================================================
9+
// Shared "for frameworks" guard for React Native's C++ stable API.
10+
//
11+
// Include this header at the top of every *for-frameworks* module header:
12+
//
13+
// #include <react/cxxstableapi/FrameworksGuard.h>
14+
//
15+
// "For frameworks" headers are APIs intended for framework authors integrating
16+
// React Native, not for ordinary app code. Including one directly emits a
17+
// SUPPRESSIBLE warning under enforcement. A framework author acknowledges the
18+
// usage by defining `RN_ALLOW_FRAMEWORKS`, which silences the warning.
19+
//
20+
// See <react/cxxstableapi/UmbrellaGuard.h> for the full `RN_*` macro contract.
21+
// In short:
22+
// RN_STRICT_API Consumer opt-in master switch; the guard is inert
23+
// without it.
24+
// RN_ALLOW_FRAMEWORKS Consumer opt-out acknowledging framework-tier usage.
25+
// RN_UMBRELLA_CONTEXT Internal marker set by an umbrella around its includes.
26+
// RN_BUILDING Set by React Native's own build.
27+
//
28+
// This header is intentionally NOT `#pragma once`-guarded: it must be
29+
// re-evaluated on every inclusion so each direct include is checked.
30+
// =============================================================================
31+
32+
#if defined(RN_STRICT_API) && !defined(RN_ALLOW_FRAMEWORKS) && !defined(RN_UMBRELLA_CONTEXT) && !defined(RN_BUILDING)
33+
#warning \
34+
"This is a 'for frameworks' React Native API, intended for framework authors rather than app code. Include it via the module umbrella <React/<Module>.h>, or define RN_ALLOW_FRAMEWORKS to acknowledge framework-tier usage and silence this warning."
35+
#endif
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
// =============================================================================
9+
// Shared "private" guard for React Native's C++ stable API.
10+
//
11+
// Include this header at the top of every *private* module header (right after
12+
// `#pragma once`):
13+
//
14+
// #include <react/cxxstableapi/PrivateGuard.h>
15+
//
16+
// Private headers are implementation details with no stability guarantee.
17+
// Including one from outside React Native's own build is a hard error under
18+
// enforcement; there is no consumer-facing escape hatch (unlike the
19+
// for-frameworks guard) — only React Native's own sources, which define
20+
// `RN_BUILDING`, may include these headers.
21+
//
22+
// See <react/cxxstableapi/UmbrellaGuard.h> for the full `RN_*` macro contract.
23+
// In short:
24+
// RN_STRICT_API Consumer opt-in master switch; the guard is inert without it.
25+
// RN_BUILDING Set by React Native's own build.
26+
//
27+
// This header is intentionally NOT `#pragma once`-guarded: it must be
28+
// re-evaluated on every inclusion so each direct include is checked.
29+
// =============================================================================
30+
31+
#if defined(RN_STRICT_API) && !defined(RN_BUILDING)
32+
#error \
33+
"This is a private React Native header and is not part of the public API. Do not include it directly; it has no stability guarantee."
34+
#endif
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
#
3+
# This source code is licensed under the MIT license found in the
4+
# LICENSE file in the root directory of this source tree.
5+
6+
require "json"
7+
8+
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "..", "package.json")))
9+
version = package['version']
10+
11+
source = { :git => 'https://github.com/facebook/react-native.git' }
12+
if version == '1000.0.0'
13+
# This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
14+
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
15+
else
16+
source[:tag] = "v#{version}"
17+
end
18+
19+
Pod::Spec.new do |s|
20+
s.name = "React-cxxstableapi"
21+
s.version = version
22+
s.summary = "Header-only guards for React Native's C++ stable API."
23+
s.homepage = "https://reactnative.dev/"
24+
s.license = package["license"]
25+
s.author = "Meta Platforms, Inc. and its affiliates"
26+
s.platforms = min_supported_versions
27+
s.source = source
28+
s.source_files = podspec_sources("*.h", "*.h")
29+
s.header_dir = "react/cxxstableapi"
30+
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
31+
"DEFINES_MODULE" => "YES" }
32+
33+
resolve_use_frameworks(s, header_mappings_dir: "../..", module_name: "React_cxxstableapi")
34+
end
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
// =============================================================================
9+
// Shared "public API" guard for React Native's C++ stable API.
10+
//
11+
// Include this header at the top of every *public* module header (right after
12+
// `#pragma once`):
13+
//
14+
// #include <react/cxxstableapi/UmbrellaGuard.h>
15+
//
16+
// The guard turns a *direct* include of a public module header into a hard
17+
// error, steering consumers to the module's umbrella header instead:
18+
//
19+
// #include <React/<Module>.h> // do this
20+
//
21+
// -----------------------------------------------------------------------------
22+
// Macro contract (all `RN_*` macros are shared across modules)
23+
//
24+
// RN_STRICT_API Consumer opt-in master switch. Every guard in this
25+
// directory is INERT unless the consuming build defines
26+
// this macro. Shipping the guards therefore changes
27+
// nothing for existing consumers — they only activate
28+
// when a consumer opts into the strict public API by
29+
// defining RN_STRICT_API.
30+
//
31+
// RN_UMBRELLA_CONTEXT Internal marker (implementation detail; consumers never
32+
// set it). A module umbrella defines it around its own
33+
// `#include`s to signal the blessed inclusion path:
34+
// #define RN_UMBRELLA_CONTEXT
35+
// #include <react/.../PublicHeaderA.h>
36+
// #include <react/.../PublicHeaderB.h>
37+
// #undef RN_UMBRELLA_CONTEXT
38+
// The `#undef` matters: it keeps the marker scoped to the
39+
// umbrella's includes so later *direct* includes in the
40+
// same translation unit are still caught.
41+
//
42+
// RN_BUILDING Defined by React Native's own build targets so internal
43+
// sources may keep including the fine-grained headers
44+
// directly.
45+
//
46+
// This header is intentionally NOT `#pragma once`-guarded: it must be
47+
// re-evaluated on every inclusion so each direct include is checked.
48+
// =============================================================================
49+
50+
#if defined(RN_STRICT_API) && !defined(RN_UMBRELLA_CONTEXT) && !defined(RN_BUILDING)
51+
#error \
52+
"Do not include this React Native header directly. Include the module's umbrella header <React/<Module>.h> instead."
53+
#endif

packages/react-native/scripts/react_native_pods.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ def use_react_native! (
148148
pod 'React-RCTVibration', :path => "#{prefix}/Libraries/Vibration"
149149
pod 'React-Core/RCTWebSocket', :path => "#{prefix}/"
150150
pod 'React-cxxreact', :path => "#{prefix}/ReactCommon/cxxreact"
151+
pod 'React-cxxstableapi', :path => "#{prefix}/ReactCommon/react/cxxstableapi"
151152
pod 'React-debug', :path => "#{prefix}/ReactCommon/react/debug"
152153
pod 'React-utils', :path => "#{prefix}/ReactCommon/react/utils"
153154
pod 'React-featureflags', :path => "#{prefix}/ReactCommon/react/featureflags"

0 commit comments

Comments
 (0)