diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt index 3301946072f7..068737880a96 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateAutolinkingNewArchitecturesFileTask.kt @@ -266,11 +266,10 @@ abstract class GenerateAutolinkingNewArchitecturesFileTask : DefaultTask() { #pragma once - #include - #include - #include + #include + #include + #include #include - #include namespace facebook { namespace react { diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt index cce6aaa6b746..02b63412c8f0 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt @@ -12,6 +12,7 @@ import com.android.build.api.variant.Variant import com.facebook.react.ReactExtension import com.facebook.react.internal.StubPchBuildService import com.facebook.react.utils.ProjectUtils.getReactNativeArchitectures +import com.facebook.react.utils.ProjectUtils.isStrictCxxApiEnabled import java.io.File import org.gradle.api.Project @@ -58,6 +59,9 @@ internal object NdkConfiguratorUtils { if (cmakeArgs.none { it.startsWith("-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES") }) { cmakeArgs.add("-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON") } + if (project.isStrictCxxApiEnabled && cmakeArgs.none { it.startsWith("-DRN_STRICT_API") }) { + cmakeArgs.add("-DRN_STRICT_API=ON") + } val architectures = project.getReactNativeArchitectures() // abiFilters are split ABI are not compatible each other, so we set the abiFilters diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt index 2a4d6cf7115d..855e34df90ab 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt @@ -15,7 +15,9 @@ import com.facebook.react.utils.PropertyUtils.REACT_NATIVE_ARCHITECTURES import com.facebook.react.utils.PropertyUtils.SCOPED_EDGE_TO_EDGE_ENABLED import com.facebook.react.utils.PropertyUtils.SCOPED_HERMES_ENABLED import com.facebook.react.utils.PropertyUtils.SCOPED_REACT_NATIVE_ARCHITECTURES +import com.facebook.react.utils.PropertyUtils.SCOPED_STRICT_CXX_API_ENABLED import com.facebook.react.utils.PropertyUtils.SCOPED_USE_THIRD_PARTY_JSC +import com.facebook.react.utils.PropertyUtils.STRICT_CXX_API_ENABLED import com.facebook.react.utils.PropertyUtils.USE_THIRD_PARTY_JSC import org.gradle.api.Project import org.gradle.api.file.DirectoryProperty @@ -56,6 +58,13 @@ internal object ProjectUtils { (project.hasProperty(SCOPED_EDGE_TO_EDGE_ENABLED) && project.property(SCOPED_EDGE_TO_EDGE_ENABLED).toString().toBoolean()) + internal val Project.isStrictCxxApiEnabled: Boolean + get() = + (project.hasProperty(STRICT_CXX_API_ENABLED) && + project.property(STRICT_CXX_API_ENABLED).toString().toBoolean()) || + (project.hasProperty(SCOPED_STRICT_CXX_API_ENABLED) && + project.property(SCOPED_STRICT_CXX_API_ENABLED).toString().toBoolean()) + internal val Project.useThirdPartyJSC: Boolean get() = (project.hasProperty(USE_THIRD_PARTY_JSC) && diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt index a0c57e759734..3425aa4ac380 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt @@ -29,6 +29,13 @@ object PropertyUtils { const val EDGE_TO_EDGE_ENABLED = "edgeToEdgeEnabled" const val SCOPED_EDGE_TO_EDGE_ENABLED = "react.edgeToEdgeEnabled" + /** + * Public property that enforces the C++ stable API for the app's own native code by defining + * RN_STRICT_API + */ + const val STRICT_CXX_API_ENABLED = "strictCxxApiEnabled" + const val SCOPED_STRICT_CXX_API_ENABLED = "react.strictCxxApiEnabled" + /** Public property that excludes jsctooling from core */ const val USE_THIRD_PARTY_JSC = "useThirdPartyJSC" const val SCOPED_USE_THIRD_PARTY_JSC = "react.useThirdPartyJSC" diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/ProjectUtilsTest.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/ProjectUtilsTest.kt index 491dd9b9545d..64fb15c42494 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/ProjectUtilsTest.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/ProjectUtilsTest.kt @@ -15,6 +15,7 @@ import com.facebook.react.utils.ProjectUtils.getReactNativeArchitectures import com.facebook.react.utils.ProjectUtils.isEdgeToEdgeEnabled import com.facebook.react.utils.ProjectUtils.isHermesEnabled import com.facebook.react.utils.ProjectUtils.isNewArchEnabled +import com.facebook.react.utils.ProjectUtils.isStrictCxxApiEnabled import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson import java.io.File import org.assertj.core.api.Assertions.assertThat @@ -115,6 +116,39 @@ class ProjectUtilsTest { assertThat(project.isEdgeToEdgeEnabled).isFalse() } + @Test + fun isStrictCxxApiEnabled_returnsFalseByDefault() { + assertThat(createProject().isStrictCxxApiEnabled).isFalse() + } + + @Test + fun isStrictCxxApiEnabled_withEnabledViaProperty_returnsTrue() { + val project = createProject() + project.extensions.extraProperties.set("strictCxxApiEnabled", "true") + assertThat(project.isStrictCxxApiEnabled).isTrue() + } + + @Test + fun isStrictCxxApiEnabled_withEnabledViaScopedProperty_returnsTrue() { + val project = createProject() + project.extensions.extraProperties.set("react.strictCxxApiEnabled", "true") + assertThat(project.isStrictCxxApiEnabled).isTrue() + } + + @Test + fun isStrictCxxApiEnabled_withDisabledViaProperty_returnsFalse() { + val project = createProject() + project.extensions.extraProperties.set("strictCxxApiEnabled", "false") + assertThat(project.isStrictCxxApiEnabled).isFalse() + } + + @Test + fun isStrictCxxApiEnabled_withInvalidViaProperty_returnsFalse() { + val project = createProject() + project.extensions.extraProperties.set("strictCxxApiEnabled", "¯\\_(ツ)_/¯") + assertThat(project.isStrictCxxApiEnabled).isFalse() + } + @Test fun needsCodegenFromPackageJson_withCodegenConfigInPackageJson_returnsTrue() { val project = createProject() diff --git a/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake b/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake index 7201024de326..7791dacd6a96 100644 --- a/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake +++ b/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake @@ -89,6 +89,11 @@ target_link_libraries(${CMAKE_PROJECT_NAME} add_library(common_flags INTERFACE) target_compile_options(common_flags INTERFACE ${folly_FLAGS}) +if(RN_STRICT_API) + target_compile_definitions(common_flags INTERFACE RN_STRICT_API) + target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE RN_STRICT_API) +endif() + # Defines the `reactnative_pch` target and `target_reuse_reactnative_pch()`, so # the codegen targets below share a single precompiled header. Has to come after # `common_flags`, as the precompiled header is built with the same flags as its diff --git a/packages/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp b/packages/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp index 3e0915c8304b..f79eb1a45512 100644 --- a/packages/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp +++ b/packages/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp @@ -30,9 +30,9 @@ #include #include #include +#include #include #include -#include #ifdef REACT_NATIVE_APP_CODEGEN_HEADER #include REACT_NATIVE_APP_CODEGEN_HEADER diff --git a/packages/react-native/ReactAndroid/cmake-utils/precompiled-header/pch.h b/packages/react-native/ReactAndroid/cmake-utils/precompiled-header/pch.h index e5ea7310a482..88e26e7285aa 100644 --- a/packages/react-native/ReactAndroid/cmake-utils/precompiled-header/pch.h +++ b/packages/react-native/ReactAndroid/cmake-utils/precompiled-header/pch.h @@ -7,15 +7,10 @@ #pragma once -#include -#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h index 8f5a2ce92d04..64338df3b8ca 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include "EventBeatManager.h" diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/ComponentFactory.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/ComponentFactory.h index e6b72a28173e..f49f7a58b0a9 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/ComponentFactory.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/ComponentFactory.h @@ -7,9 +7,8 @@ #pragma once +#include #include -#include -#include namespace facebook::react { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CoreComponentsRegistry.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CoreComponentsRegistry.h index 36eec9bbae7b..3e09c9716db8 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CoreComponentsRegistry.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CoreComponentsRegistry.h @@ -7,7 +7,7 @@ #pragma once -#include +#include namespace facebook::react::CoreComponentsRegistry { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h index 50143ad8f6c9..4186c374f848 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h @@ -7,9 +7,9 @@ #pragma once +#include #include #include -#include namespace facebook::react { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h index 7ed9262f660b..fb4a0d39c465 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h @@ -10,10 +10,9 @@ #include #include +#include #include #include -#include -#include namespace facebook::react { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/StateWrapperImpl.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/StateWrapperImpl.h index 6e107180b555..39236a319d67 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/StateWrapperImpl.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/StateWrapperImpl.h @@ -7,10 +7,10 @@ #pragma once +#include #include #include #include -#include #include namespace facebook::react { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h b/packages/react-native/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h index 9caffec9c434..9c0fe9dbda66 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include namespace facebook::react { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.h b/packages/react-native/ReactAndroid/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.h index aed8d355ad13..fc8a329fc1f7 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.h @@ -7,9 +7,9 @@ #pragma once +#include +#include #include -#include -#include #include diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.h b/packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.h index b432b1a53714..feac6daa2a8e 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.h @@ -7,11 +7,10 @@ #pragma once +#include +#include #include #include -#include -#include -#include namespace facebook::react { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.h b/packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.h index c8f87d39ce91..dc5dd8989506 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.h @@ -9,9 +9,8 @@ #include #include +#include #include -#include -#include #include #include diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/BindingsInstallerHolder.h b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/BindingsInstallerHolder.h index 1ca58bba4399..6501f4fc7094 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/BindingsInstallerHolder.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/BindingsInstallerHolder.h @@ -7,8 +7,8 @@ #pragma once -#include -#include +#include +#include #include namespace facebook::react { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.h b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.h index ca1fd0ff3e39..f0a6eda8d8f8 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h index b6f9b1aed4c4..d54b493e45fa 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h index 0cc6a096436e..375bbfd4b91f 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h @@ -12,11 +12,10 @@ #include #include +#include +#include #include -#include #include -#include -#include #include #include diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManagerDelegate.h b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManagerDelegate.h index ce7ac58fa364..6dfd3c996037 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManagerDelegate.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManagerDelegate.h @@ -7,8 +7,8 @@ #pragma once -#include -#include +#include +#include #include #include #include diff --git a/packages/rn-tester/android/app/src/main/jni/OnLoad.cpp b/packages/rn-tester/android/app/src/main/jni/OnLoad.cpp index 72d62fb09590..c54faffa30ee 100644 --- a/packages/rn-tester/android/app/src/main/jni/OnLoad.cpp +++ b/packages/rn-tester/android/app/src/main/jni/OnLoad.cpp @@ -9,9 +9,9 @@ #include #include #include +#include #include #include -#include #ifdef REACT_NATIVE_APP_CODEGEN_HEADER #include REACT_NATIVE_APP_CODEGEN_HEADER