From 6add48e9110baf6de6d737760663d9aa5d0482b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Fri, 21 Nov 2025 15:26:35 +0100 Subject: [PATCH 1/8] feat(Worklets): public RNWorklets headers --- apps/fabric-example/ios/Podfile.lock | 62 ++++++++++++++++++- apps/macos-example/macos/Podfile.lock | 52 +++++++++++++++- apps/tvos-example/ios/Podfile.lock | 60 +++++++++++++++++- .../docs/threading/scheduleOnRuntime.mdx | 2 +- .../AnimatedSensor/AnimatedSensorModule.h | 4 +- .../LayoutAnimationsManager.h | 2 +- .../NativeModules/ReanimatedModuleProxy.cpp | 2 +- .../android/CMakeLists.txt | 3 +- .../worklets/{Public => RunLoop}/AsyncQueue.h | 5 +- .../cpp/worklets/RunLoop/AsyncQueueImpl.h | 2 +- .../Common/cpp/worklets/RunLoop/EventLoop.h | 2 +- .../cpp/worklets/SharedItems/Serializable.h | 5 +- .../cpp/worklets/SharedItems/Synchronizable.h | 5 +- .../worklets/WorkletRuntime/WorkletRuntime.h | 7 ++- .../react-native-worklets/RNWorklets.podspec | 16 ++++- .../android/build.gradle | 16 +++++ .../src/runtimes.native.ts | 2 +- packages/react-native-worklets/src/types.ts | 4 +- 18 files changed, 229 insertions(+), 22 deletions(-) rename packages/react-native-worklets/Common/cpp/worklets/{Public => RunLoop}/AsyncQueue.h (69%) diff --git a/apps/fabric-example/ios/Podfile.lock b/apps/fabric-example/ios/Podfile.lock index 6d0908d25d58..837c94061750 100644 --- a/apps/fabric-example/ios/Podfile.lock +++ b/apps/fabric-example/ios/Podfile.lock @@ -2875,6 +2875,8 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - RNWorklets/worklets/apple (= 0.7.0-main) + - RNWorklets/worklets/common (= 0.7.0-main) + - RNWorklets/worklets/public (= 0.7.0-main) - SocketRocket - Yoga - RNWorklets/worklets/apple (0.7.0-main): @@ -2906,6 +2908,64 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga + - RNWorklets/worklets/common (0.7.0-main): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - RNWorklets/worklets/public (0.7.0-main): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - SocketRocket (0.7.1) - Yoga (0.0.0) @@ -3261,7 +3321,7 @@ SPEC CHECKSUMS: RNReanimated: 97ebf4d3c76929b6b0f866cfbd41c49b3a0d2dbf RNScreens: 0bbf16c074ae6bb1058a7bf2d1ae017f4306797c RNSVG: 8c0bbfa480a24b24468f1c76bd852a4aac3178e6 - RNWorklets: f54a415f73a3fc653bfe65e599872fdc6bca0477 + RNWorklets: b2ad4ec784199346ed45f0d2eec051401d383c2d SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: edeb9900b9e5bb5b27b9a6a2d5914e4fe4033c1b diff --git a/apps/macos-example/macos/Podfile.lock b/apps/macos-example/macos/Podfile.lock index fe67bd1fef42..85a8ecc6bde4 100644 --- a/apps/macos-example/macos/Podfile.lock +++ b/apps/macos-example/macos/Podfile.lock @@ -1977,6 +1977,8 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - RNWorklets/worklets/apple (= 0.7.0-main) + - RNWorklets/worklets/common (= 0.7.0-main) + - RNWorklets/worklets/public (= 0.7.0-main) - Yoga - RNWorklets/worklets/apple (0.7.0-main): - DoubleConversion @@ -2002,6 +2004,54 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga + - RNWorklets/worklets/common (0.7.0-main): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.11.18.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga + - RNWorklets/worklets/public (0.7.0-main): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.11.18.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - SocketRocket (0.7.1) - Yoga (0.0.0) @@ -2322,7 +2372,7 @@ SPEC CHECKSUMS: RNGestureHandler: 0397fea67f39d5a2d17fcf4a028e206f7ba098ba RNReanimated: 152207cf096f2badeef2c552a8f2886accd187e6 RNSVG: 681f8ef5ca50e13cb3c6c88a907ea89b68fee74f - RNWorklets: ee84c4d458ce35f4ed94462a2add070ff4e69edb + RNWorklets: 7cdcdb8dd199bc5d1cd99e42940c47e4442a2670 SocketRocket: 03f7111df1a343b162bf5b06ead333be808e1e0a Yoga: 45ce05cb11db042ba2e5e51a2dfaf0ff63d269f9 diff --git a/apps/tvos-example/ios/Podfile.lock b/apps/tvos-example/ios/Podfile.lock index 4bf4190b204b..7594d92ede21 100644 --- a/apps/tvos-example/ios/Podfile.lock +++ b/apps/tvos-example/ios/Podfile.lock @@ -2397,6 +2397,8 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - RNWorklets/worklets/apple (= 0.7.0-main) + - RNWorklets/worklets/common (= 0.7.0-main) + - RNWorklets/worklets/public (= 0.7.0-main) - SocketRocket - Yoga - RNWorklets/worklets/apple (0.7.0-main): @@ -2427,6 +2429,62 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga + - RNWorklets/worklets/common (0.7.0-main): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - RNWorklets/worklets/public (0.7.0-main): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - SocketRocket (0.7.1) - Yoga (0.0.0) @@ -2732,7 +2790,7 @@ SPEC CHECKSUMS: ReactCodegen: f4d6e6fd5140eade461ffb5579795197956868c8 ReactCommon: c178596d3ef05508bb6c0f88bfbbc281b5c4222b RNReanimated: cccf8b45cb675080e7c5f3a4f5d0498eff6c62a0 - RNWorklets: 339aa12272b2ff6490d91526e8ced6599f7ef6a3 + RNWorklets: 6aa271764dc8121f468b10c866239ca4c644208b SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: 0e792f39294e864568930600eeb71135364f777d diff --git a/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx b/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx index 9d3b52085ebe..7aada0f8eb83 100644 --- a/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx +++ b/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx @@ -48,7 +48,7 @@ Arguments to the function you want to execute on the [Worker Runtime](/docs/fund ## Remarks - The worklet is scheduled on the Worker Runtime's [Async - Queue](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h) + Queue](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h) - The worklet cannot be scheduled on the Worker Runtime from [UI Runtime](/docs/fundamentals/glossary#ui-runtime) or another [Worker Runtime](/docs/fundamentals/glossary#worker-runtime), unless the [Bundle Mode](/docs/experimental/bundleMode) is enabled. diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.h b/packages/react-native-reanimated/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.h index 2964ac3a16f9..521bbf325b53 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.h @@ -2,8 +2,8 @@ #include -#include -#include +#include +#include #include diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.h b/packages/react-native-reanimated/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.h index 16de0b56a16b..c5b5c3065fcf 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.h @@ -2,7 +2,7 @@ #include -#include +#include #include #include diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp b/packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp index 454eeb1a4cc0..a3d3271e68aa 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +++ b/packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp @@ -5,8 +5,8 @@ #include #include +#include #include -#include #include #ifdef __ANDROID__ diff --git a/packages/react-native-reanimated/android/CMakeLists.txt b/packages/react-native-reanimated/android/CMakeLists.txt index d4731e6c9e5b..9f3220d6315e 100644 --- a/packages/react-native-reanimated/android/CMakeLists.txt +++ b/packages/react-native-reanimated/android/CMakeLists.txt @@ -70,7 +70,8 @@ target_include_directories( "${REACT_NATIVE_DIR}/ReactCommon/jsiexecutor" "${REACT_NATIVE_DIR}/ReactCommon/react/renderer/graphics/platform/cxx" "${REACT_NATIVE_WORKLETS_DIR}/Common/cpp" - "${REACT_NATIVE_WORKLETS_DIR}/android/src/main/cpp") + "${REACT_NATIVE_WORKLETS_DIR}/android/src/main/cpp" + "${REACT_NATIVE_WORKLETS_DIR}/android/build/prefab-headers") set_target_properties(reanimated PROPERTIES LINKER_LANGUAGE CXX) diff --git a/packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h similarity index 69% rename from packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h rename to packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h index 0ec5146437ad..9ddee394f642 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h +++ b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef RNWORKLETS_ASYNCQUEUE_H +#define RNWORKLETS_ASYNCQUEUE_H #include @@ -12,3 +13,5 @@ class AsyncQueue : public facebook::jsi::NativeState { }; } // namespace worklets + +#endif // RNWORKLETS_ASYNCQUEUE_H diff --git a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h index 30cd0d7a0292..72592049201b 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h +++ b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include diff --git a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/EventLoop.h b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/EventLoop.h index ac3eed1816d1..885bbbe2a8c1 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/EventLoop.h +++ b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/EventLoop.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include diff --git a/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Serializable.h b/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Serializable.h index 771b6be96cd9..90b693ae79da 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Serializable.h +++ b/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Serializable.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef RNWORKLETS_SERIALIZABLE_H +#define RNWORKLETS_SERIALIZABLE_H #include @@ -429,3 +430,5 @@ struct SerializationData { }; } // namespace worklets + +#endif // RNWORKLETS_SERIALIZABLE_H diff --git a/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Synchronizable.h b/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Synchronizable.h index 55e3a56eafb2..b126e0bbb1aa 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Synchronizable.h +++ b/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Synchronizable.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef RNWORKLETS_SYNCHRONIZABLE_H +#define RNWORKLETS_SYNCHRONIZABLE_H #include #include @@ -55,3 +56,5 @@ jsi::Function getSynchronizableUnpacker(jsi::Runtime &rt); std::shared_ptr extractSynchronizableOrThrow(jsi::Runtime &rt, const jsi::Value &value); }; // namespace worklets + +#endif // RNWORKLETS_SYNCHRONIZABLE_H diff --git a/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h b/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h index 919f0de2e95d..ce5845665c71 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +++ b/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h @@ -1,11 +1,12 @@ -#pragma once +#ifndef RNWORKLETS_WORKLETRUNTIME_H +#define RNWORKLETS_WORKLETRUNTIME_H #include #include #include #include -#include +#include #include #include #include @@ -215,3 +216,5 @@ inline jsi::Value runOnRuntimeGuarded(jsi::Runtime &rt, const jsi::Value &functi } } // namespace worklets + +#endif // RNWORKLETS_WORKLETRUNTIME_H diff --git a/packages/react-native-worklets/RNWorklets.podspec b/packages/react-native-worklets/RNWorklets.podspec index fa66aa9ef6f6..44c3e766dd4d 100644 --- a/packages/react-native-worklets/RNWorklets.podspec +++ b/packages/react-native-worklets/RNWorklets.podspec @@ -24,9 +24,11 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/software-mansion/react-native-reanimated.git", :tag => "#{s.version}" } s.subspec "worklets" do |ss| - ss.source_files = "Common/cpp/worklets/**/*.{cpp,h}" - ss.header_dir = "worklets" - ss.header_mappings_dir = "Common/cpp/worklets" + ss.subspec "common" do |sss| + sss.source_files = "Common/cpp/worklets/**/*.{h,cpp}" + sss.header_dir = "worklets" + sss.header_mappings_dir = "Common/cpp/worklets" + end ss.subspec "apple" do |sss| # Please be careful with the snakes. @@ -36,6 +38,14 @@ Pod::Spec.new do |s| sss.header_dir = "worklets" sss.header_mappings_dir = "apple/worklets" end + + ss.subspec "public" do |sss| + sss.source_files = + "Common/cpp/worklets/RunLoop/AsyncQueue.h", + "Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h", + "Common/cpp/worklets/SharedItems/Serializable.h", + "Common/cpp/worklets/SharedItems/Synchronizable.h" + end end # Use install_modules_dependencies helper to install the dependencies. diff --git a/packages/react-native-worklets/android/build.gradle b/packages/react-native-worklets/android/build.gradle index 2e5ad454afb1..087c2c7c7d90 100644 --- a/packages/react-native-worklets/android/build.gradle +++ b/packages/react-native-worklets/android/build.gradle @@ -108,6 +108,7 @@ def HERMES_V1_ENABLED = safeAppExtGet("hermesV1Enabled", false) version WORKLETS_VERSION def workletsPrefabHeadersDir = project.file("$buildDir/prefab-headers/worklets") +def RNWorkletsPrefabHeadersDir = project.file("${buildDir}/prefab-headers/RNWorklets") def JS_RUNTIME = { // Override JS runtime with environment variable @@ -172,6 +173,7 @@ android { prefab { worklets { headers workletsPrefabHeadersDir.absolutePath + headers RNWorkletsPrefabHeadersDir.absolutePath } } @@ -315,6 +317,20 @@ task prepareWorkletsHeadersForPrefabs(type: Copy) { from("$projectDir/../Common/cpp") include("worklets/**/*.h") into(workletsPrefabHeadersDir) + + // Pack public headers to RNWorklets headers dir + from("$projectDir/../Common/cpp/worklets/RunLoop/") { + include("AsyncQueue.h") + } + from("$projectDir/../Common/cpp/worklets/WorkletRuntime/") { + include("WorkletRuntime.h") + } + from("$projectDir/../Common/cpp/worklets/SharedItems/") { + include("Serializable.h") + include("Synchronizable.h") + } + into(RNWorkletsPrefabHeadersDir) + } task cleanCmakeCache() { diff --git a/packages/react-native-worklets/src/runtimes.native.ts b/packages/react-native-worklets/src/runtimes.native.ts index 5cd234e89b90..c1cd1dd8c83b 100644 --- a/packages/react-native-worklets/src/runtimes.native.ts +++ b/packages/react-native-worklets/src/runtimes.native.ts @@ -115,7 +115,7 @@ export function createWorkletRuntime( * for more information about the different runtime kinds. * * - The worklet is scheduled on the Worker Runtime's [Async - * Queue](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h) + * Queue](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h) * - The function cannot be scheduled on the Worker Runtime from [UI * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#ui-runtime) * or another [Worker diff --git a/packages/react-native-worklets/src/types.ts b/packages/react-native-worklets/src/types.ts index 916e175a4a1f..892e47eb10f9 100644 --- a/packages/react-native-worklets/src/types.ts +++ b/packages/react-native-worklets/src/types.ts @@ -130,7 +130,7 @@ export type WorkletRuntimeConfig = { * An optional custom queue to be used for scheduling worklets. * * The queue has to implement the C++ `AsyncQueue` interface from - * ``. + * ``. */ customQueue?: never; } @@ -144,7 +144,7 @@ export type WorkletRuntimeConfig = { * An optional custom queue to be used for scheduling worklets. * * The queue has to implement the C++ `AsyncQueue` interface from - * ``. + * ``. */ customQueue?: object; } From db3b34b84390718bdc1a08fb2aac1527bb0533a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Mon, 24 Nov 2025 20:18:57 +0100 Subject: [PATCH 2/8] chore: wip --- ...-gradle-plugin-npm-0.82.0-10aedc0588.patch | 15 +++ apps/fabric-example/android/gradle.properties | 7 +- package.json | 3 + .../android/CMakeLists.txt | 17 +-- .../android/build.gradle | 15 ++- .../android/fix-prefab.gradle | 51 ++++++++ .../Common/cpp/worklets/RunLoop/AsyncQueue.h | 5 +- .../cpp/worklets/SharedItems/Serializable.h | 5 +- .../cpp/worklets/SharedItems/Synchronizable.h | 5 +- .../worklets/WorkletRuntime/WorkletRuntime.h | 5 +- .../android/CMakeLists.txt | 40 +++++- .../android/build.gradle | 122 ++++++++++++++---- .../android/fix-prefab.gradle | 69 ++++++++++ yarn.lock | 7 + 14 files changed, 308 insertions(+), 58 deletions(-) create mode 100644 .yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch create mode 100644 packages/react-native-reanimated/android/fix-prefab.gradle create mode 100644 packages/react-native-worklets/android/fix-prefab.gradle diff --git a/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch b/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch new file mode 100644 index 000000000000..4a729e21a42f --- /dev/null +++ b/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch @@ -0,0 +1,15 @@ +diff --git a/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt b/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +index 890e61c007d5b3e0a9a69d37ef10e8aa3ce5c6b6..91acd7b2930fedb4eca2461ba99287721ca1f38f 100644 +--- a/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt ++++ b/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +@@ -80,7 +80,9 @@ class ReactPlugin : Plugin { + configureRepositories(project) + } + +- configureReactNativeNdk(project, extension) ++ if(!project.gradle.startParameter.taskNames.any { it.contains("clean") }) { ++ configureReactNativeNdk(project, extension) ++ } + configureBuildConfigFieldsForApp(project, extension) + configureDevServerLocation(project) + configureBackwardCompatibilityReactMap(project) diff --git a/apps/fabric-example/android/gradle.properties b/apps/fabric-example/android/gradle.properties index d183897bec8e..dc802ce5753e 100644 --- a/apps/fabric-example/android/gradle.properties +++ b/apps/fabric-example/android/gradle.properties @@ -25,7 +25,8 @@ android.useAndroidX=true # Use this property to specify which architecture you want to build. # You can also override it from the CLI using # ./gradlew -PreactNativeArchitectures=x86_64 -reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 +# reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 +reactNativeArchitectures=arm64-v8a # Use this property to enable support to the new architecture. # This will allow you to use TurboModules and the Fabric render in @@ -52,5 +53,5 @@ enableReanimatedProfiling=true # workletsBundleMode=true # https://docs.gradle.org/current/userguide/configuration_cache.html -org.gradle.configuration-cache=true -org.gradle.configuration-cache.problems=fail +# org.gradle.configuration-cache=true +# org.gradle.configuration-cache.problems=fail diff --git a/package.json b/package.json index 141335c03687..81b7447f4021 100644 --- a/package.json +++ b/package.json @@ -70,5 +70,8 @@ "react-native-builder-bob": "0.40.13", "shelljs": "0.10.0", "typescript": "5.8.3" + }, + "resolutions": { + "@react-native/gradle-plugin@npm:0.82.0": "patch:@react-native/gradle-plugin@npm%3A0.82.0#~/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch" } } diff --git a/packages/react-native-reanimated/android/CMakeLists.txt b/packages/react-native-reanimated/android/CMakeLists.txt index 9f3220d6315e..db5338ada627 100644 --- a/packages/react-native-reanimated/android/CMakeLists.txt +++ b/packages/react-native-reanimated/android/CMakeLists.txt @@ -45,6 +45,7 @@ file(GLOB_RECURSE REANIMATED_ANDROID_CPP_SOURCES CONFIGURE_DEPENDS find_package(fbjni REQUIRED CONFIG) find_package(ReactAndroid REQUIRED CONFIG) +find_package(react-native-worklets REQUIRED CONFIG) add_library(reanimated SHARED ${REANIMATED_COMMON_CPP_SOURCES} ${REANIMATED_ANDROID_CPP_SOURCES}) @@ -71,7 +72,9 @@ target_include_directories( "${REACT_NATIVE_DIR}/ReactCommon/react/renderer/graphics/platform/cxx" "${REACT_NATIVE_WORKLETS_DIR}/Common/cpp" "${REACT_NATIVE_WORKLETS_DIR}/android/src/main/cpp" - "${REACT_NATIVE_WORKLETS_DIR}/android/build/prefab-headers") + # Official public headers of react-native-worklets + # "${BUILD_DIR}/include" +) set_target_properties(reanimated PROPERTIES LINKER_LANGUAGE CXX) @@ -83,12 +86,9 @@ endif() add_library(worklets SHARED IMPORTED) -set_target_properties( - worklets - PROPERTIES - IMPORTED_LOCATION - "${REACT_NATIVE_WORKLETS_DIR}/android/build/intermediates/cmake/${BUILD_TYPE}/obj/${ANDROID_ABI}/libworklets.so" -) +# set_target_properties( worklets PROPERTIES IMPORTED_LOCATION +# "${REACT_NATIVE_WORKLETS_DIR}/android/build/intermediates/cmake/${BUILD_TYPE}/obj/${ANDROID_ABI}/libworklets.so" +# ) set_target_properties(reanimated PROPERTIES LINKER_LANGUAGE CXX) # remove dead code sections @@ -109,4 +109,5 @@ target_link_libraries( ReactAndroid::jsi fbjni::fbjni android - worklets) + react-native-worklets::worklets + react-native-worklets::RNWorklets) diff --git a/packages/react-native-reanimated/android/build.gradle b/packages/react-native-reanimated/android/build.gradle index 86bace765ea9..58f6f9cbbbc4 100644 --- a/packages/react-native-reanimated/android/build.gradle +++ b/packages/react-native-reanimated/android/build.gradle @@ -111,6 +111,8 @@ def getReanimatedStaticFeatureFlags() { return featureFlags.collect { key, value -> "[${key}:${value}]" }.join("") } +// apply from: "./fix-prefab.gradle" + if (isNewArchitectureEnabled()) { apply plugin: "com.facebook.react" } @@ -314,12 +316,13 @@ task prepareReanimatedHeadersForPrefabs(type: Copy) { into(reanimatedPrefabHeadersDir) } -task cleanCmakeCache() { - tasks.getByName("clean").dependsOn(cleanCmakeCache) - doFirst { - delete "${projectDir}/.cxx" - } -} +// tasks.register("cleanCmakeCache", Delete) { +// delete(layout.projectDirectory.dir(".cxx")) +// delete(layout.projectDirectory.dir("build")) +// } +// tasks.named("clean") { +// dependsOn("cleanCmakeCache") +// } repositories { mavenCentral() diff --git a/packages/react-native-reanimated/android/fix-prefab.gradle b/packages/react-native-reanimated/android/fix-prefab.gradle new file mode 100644 index 000000000000..d6c010ef785b --- /dev/null +++ b/packages/react-native-reanimated/android/fix-prefab.gradle @@ -0,0 +1,51 @@ +tasks.configureEach { task -> + // Make sure that we generate our prefab publication file only after having built the native library + // so that not a header publication file, but a full configuration publication will be generated, which + // will include the .so file + + def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/ + def matcher = task.name =~ prefabConfigurePattern + if (matcher.matches()) { + def variantName = matcher[0][1] + task.outputs.upToDateWhen { false } + task.dependsOn("externalNativeBuild${variantName}") + } +} + +afterEvaluate { + def abis = reactNativeArchitectures() + rootProject.allprojects.each { proj -> + if (proj === rootProject) return + + def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config -> + config.dependencies.any { dep -> + dep.group == project.group && dep.name == project.name + } + } + if (!dependsOnThisLib && proj != project) return + + if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) { + return + } + + def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants + // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to + // generate a libnameConfig.cmake file that will contain our native library (.so). + // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue + variants.all { variant -> + def variantName = variant.name + abis.each { abi -> + def searchDir = new File(proj.projectDir, ".cxx/${variantName}") + if (!searchDir.exists()) return + def matches = [] + searchDir.eachDir { randomDir -> + def prefabFile = new File(randomDir, "${abi}/prefab_config.json") + if (prefabFile.exists()) matches << prefabFile + } + matches.each { prefabConfig -> + prefabConfig.setLastModified(System.currentTimeMillis()) + } + } + } + } +} diff --git a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h index 9ddee394f642..0ec5146437ad 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h +++ b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h @@ -1,5 +1,4 @@ -#ifndef RNWORKLETS_ASYNCQUEUE_H -#define RNWORKLETS_ASYNCQUEUE_H +#pragma once #include @@ -13,5 +12,3 @@ class AsyncQueue : public facebook::jsi::NativeState { }; } // namespace worklets - -#endif // RNWORKLETS_ASYNCQUEUE_H diff --git a/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Serializable.h b/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Serializable.h index 90b693ae79da..771b6be96cd9 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Serializable.h +++ b/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Serializable.h @@ -1,5 +1,4 @@ -#ifndef RNWORKLETS_SERIALIZABLE_H -#define RNWORKLETS_SERIALIZABLE_H +#pragma once #include @@ -430,5 +429,3 @@ struct SerializationData { }; } // namespace worklets - -#endif // RNWORKLETS_SERIALIZABLE_H diff --git a/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Synchronizable.h b/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Synchronizable.h index b126e0bbb1aa..55e3a56eafb2 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Synchronizable.h +++ b/packages/react-native-worklets/Common/cpp/worklets/SharedItems/Synchronizable.h @@ -1,5 +1,4 @@ -#ifndef RNWORKLETS_SYNCHRONIZABLE_H -#define RNWORKLETS_SYNCHRONIZABLE_H +#pragma once #include #include @@ -56,5 +55,3 @@ jsi::Function getSynchronizableUnpacker(jsi::Runtime &rt); std::shared_ptr extractSynchronizableOrThrow(jsi::Runtime &rt, const jsi::Value &value); }; // namespace worklets - -#endif // RNWORKLETS_SYNCHRONIZABLE_H diff --git a/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h b/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h index ce5845665c71..715c7009fa42 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +++ b/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h @@ -1,5 +1,4 @@ -#ifndef RNWORKLETS_WORKLETRUNTIME_H -#define RNWORKLETS_WORKLETRUNTIME_H +#pragma once #include #include @@ -216,5 +215,3 @@ inline jsi::Value runOnRuntimeGuarded(jsi::Runtime &rt, const jsi::Value &functi } } // namespace worklets - -#endif // RNWORKLETS_WORKLETRUNTIME_H diff --git a/packages/react-native-worklets/android/CMakeLists.txt b/packages/react-native-worklets/android/CMakeLists.txt index 7ce60581c4de..6a8a81a8a960 100644 --- a/packages/react-native-worklets/android/CMakeLists.txt +++ b/packages/react-native-worklets/android/CMakeLists.txt @@ -1,5 +1,5 @@ project(Worklets) -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.13) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -60,6 +60,19 @@ endif() add_library(worklets SHARED ${WORKLETS_COMMON_CPP_SOURCES} ${WORKLETS_ANDROID_CPP_SOURCES}) +add_library( + RNWorklets + INTERFACE + "${COMMON_CPP_DIR}/worklets/RunLoop/AsyncQueue.h" + "${COMMON_CPP_DIR}/worklets/WorkletRuntime/WorkletRuntime.h" + "${COMMON_CPP_DIR}/worklets/SharedItems/Serializable.h" + "${COMMON_CPP_DIR}/worklets/SharedItems/Synchronizable.h") + +get_target_property(WORKLETS_TYPE worklets TYPE) +get_target_property(RNWORKLETS_TYPE RNWorklets TYPE) +message(WARNING "worklets library added, type: ${WORKLETS_TYPE}") +message(WARNING "RNWorklets library added, type: ${RNWORKLETS_TYPE}") + if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 80) include( "${REACT_NATIVE_DIR}/ReactCommon/cmake-utils/react-native-flags.cmake") @@ -106,3 +119,28 @@ if(${JS_RUNTIME} STREQUAL "hermes") elseif(${JS_RUNTIME} STREQUAL "jsc") target_link_libraries(worklets ReactAndroid::jsctooling) endif() + +# get_cmake_property(_variableNames VARIABLES) list(SORT _variableNames) +# foreach(_variableName ${_variableNames}) message(WARNING "${_variableName} = +# ${${_variableName}}") endforeach() + +# set(PUBLIC_INCLUDE_DIR "${RNWORKLETS_HEADERS_DIR}") + +# file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}") + +# # // // Pack public headers to RNWorklets headers dir // # +# from("$projectDir/../Common/cpp/worklets/RunLoop/") { // # +# include("AsyncQueue.h") // } // # +# from("$projectDir/../Common/cpp/worklets/WorkletRuntime/") { // # +# include("WorkletRuntime.h") // } // # +# from("$projectDir/../Common/cpp/worklets/SharedItems/") { // # +# include("Serializable.h") // include("Synchronizable.h") // } + +# file(CREATE_LINK "${COMMON_CPP_DIR}/worklets/RunLoop/AsyncQueue.h" +# "${PUBLIC_INCLUDE_DIR}/AsyncQueue.h" SYMBOLIC) file(CREATE_LINK +# "${COMMON_CPP_DIR}/worklets/WorkletRuntime/WorkletRuntime.h" +# "${PUBLIC_INCLUDE_DIR}/WorkletRuntime.h" SYMBOLIC) file(CREATE_LINK +# "${COMMON_CPP_DIR}/worklets/SharedItems/Serializable.h" +# "${PUBLIC_INCLUDE_DIR}/Serializable.h" SYMBOLIC) file(CREATE_LINK +# "${COMMON_CPP_DIR}/worklets/SharedItems/Synchronizable.h" +# "${PUBLIC_INCLUDE_DIR}/Synchronizable.h" SYMBOLIC) diff --git a/packages/react-native-worklets/android/build.gradle b/packages/react-native-worklets/android/build.gradle index 087c2c7c7d90..aac2668dea09 100644 --- a/packages/react-native-worklets/android/build.gradle +++ b/packages/react-native-worklets/android/build.gradle @@ -1,5 +1,7 @@ import com.android.build.gradle.tasks.ExternalNativeBuildJsonTask import groovy.json.JsonSlurper + +import java.nio.file.Files import java.nio.file.Paths import org.apache.tools.ant.taskdefs.condition.Os @@ -107,8 +109,19 @@ def HERMES_V1_ENABLED = safeAppExtGet("hermesV1Enabled", false) // Set version for prefab version WORKLETS_VERSION -def workletsPrefabHeadersDir = project.file("$buildDir/prefab-headers/worklets") +def workletsPrefabHeadersDir = project.file("${buildDir}/prefab-headers/worklets") +workletsPrefabHeadersDir.mkdirs() def RNWorkletsPrefabHeadersDir = project.file("${buildDir}/prefab-headers/RNWorklets") +RNWorkletsPrefabHeadersDir.mkdirs() +def RNWorkletsPrefabHeadersAPIDir = project.file("${buildDir}/prefab-headers/RNWorklets/RNWorklets") +RNWorkletsPrefabHeadersAPIDir.mkdirs() +// def rootProjectBuildDir = rootProject.hasProperty("buildDir") ? rootProject.buildDir : "${rootProject.projectDir}/build" +// println("Root project build dir: ") +// println(rootProject) +// println(rootProject.hasProperty("buildDir")) +// println(rootProject.buildDir) +// println(rootProjectBuildDir) +// println(rootProject.projectDir) def JS_RUNTIME = { // Override JS runtime with environment variable @@ -151,6 +164,8 @@ apply plugin: "com.android.library" apply plugin: "maven-publish" apply plugin: "de.undercouch.download" +apply from: "./fix-prefab.gradle" + android { compileSdkVersion safeExtGet("compileSdkVersion", 34) @@ -173,7 +188,13 @@ android { prefab { worklets { headers workletsPrefabHeadersDir.absolutePath + headerOnly false + // headers RNWorkletsPrefabHeadersDir.absolutePath + } + RNWorklets { + // headers RNWorkletsHeadersDir.absolutePath headers RNWorkletsPrefabHeadersDir.absolutePath + headerOnly true } } @@ -201,8 +222,10 @@ android { "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON", "-DWORKLETS_FEATURE_FLAGS=${WORKLETS_FEATURE_FLAGS}", "-DHERMES_V1_ENABLED=${HERMES_V1_ENABLED}" + // , + // "-DRNWORKLETS_HEADERS_DIR=${toPlatformFileString(RNWorkletsHeadersDir.path)}" abiFilters (*reactNativeArchitectures()) - targets("worklets") + targets("worklets", "RNWorklets") } } @@ -312,34 +335,85 @@ task assertNewArchitectureEnabledTask { preBuild.dependsOn(assertNewArchitectureEnabledTask) -task prepareWorkletsHeadersForPrefabs(type: Copy) { - from("$projectDir/src/main/cpp") - from("$projectDir/../Common/cpp") - include("worklets/**/*.h") - into(workletsPrefabHeadersDir) +//tasks.register('prepareWorkletsHeadersForPrefabs',) { +task prepareWorkletsHeadersForPrefabs { + doFirst { + workletsPrefabHeadersDir.mkdirs() + RNWorkletsPrefabHeadersDir.mkdirs() + RNWorkletsPrefabHeadersAPIDir.mkdirs() + +// inputs.files(fileTree("$projectDir/src/main/cpp") { +// include '**/worklets/**/*.h' +// }) +// inputs.files(fileTree("$projectDir/../Common/cpp") { +// include '**/worklets/**/*.h' +// }) + // inputs.files([ + // file("$projectDir/../Common/cpp/worklets/RunLoop/AsyncQueue.h"), + // file("$projectDir/../Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h"), + // file("$projectDir/../Common/cpp/worklets/SharedItems/Serializable.h"), + // file("$projectDir/../Common/cpp/worklets/SharedItems/Synchronizable.h") + // ]) + + def sourceDir1 = file("$projectDir/src/main/cpp") + def sourceDir2 = file("$projectDir/../Common/cpp") + + [sourceDir1, sourceDir2].each { sourceDir -> + if (sourceDir.exists()) { + sourceDir.eachFileRecurse { sourceFile -> + if (sourceFile.isFile() && sourceFile.path.contains("worklets") && sourceFile.name.endsWith(".h")) { + def relativePath = sourceDir.toPath().relativize(sourceFile.toPath()) + def targetFile = file("${workletsPrefabHeadersDir}/${relativePath}") + + targetFile.parentFile.mkdirs() + + if (targetFile.exists()) { + targetFile.delete() + } + + Files.createSymbolicLink( + targetFile.toPath(), + sourceFile.toPath() + ) + } + } + } + } - // Pack public headers to RNWorklets headers dir - from("$projectDir/../Common/cpp/worklets/RunLoop/") { - include("AsyncQueue.h") - } - from("$projectDir/../Common/cpp/worklets/WorkletRuntime/") { - include("WorkletRuntime.h") - } - from("$projectDir/../Common/cpp/worklets/SharedItems/") { - include("Serializable.h") - include("Synchronizable.h") - } - into(RNWorkletsPrefabHeadersDir) + def sourceFiles = [ + file("$projectDir/../Common/cpp/worklets/RunLoop/AsyncQueue.h"), + file("$projectDir/../Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h"), + file("$projectDir/../Common/cpp/worklets/SharedItems/Serializable.h"), + file("$projectDir/../Common/cpp/worklets/SharedItems/Synchronizable.h") + ] -} + sourceFiles.each { sourceFile -> + def targetFile = file("${RNWorkletsPrefabHeadersAPIDir}/${sourceFile.name}") -task cleanCmakeCache() { - tasks.getByName("clean").dependsOn(cleanCmakeCache) - doFirst { - delete "${projectDir}/.cxx" + targetFile.parentFile.mkdirs() + + if (targetFile.exists()) { + targetFile.delete() + } + + Files.createSymbolicLink( + targetFile.toPath(), + sourceFile.toPath() + ) + } + +// outputs.dir(workletsPrefabHeadersDir) +// outputs.dir(RNWorkletsPrefabHeadersDir) } } +// tasks.register("cleanCmakeCache", Delete) { +// delete(layout.projectDirectory.dir(".cxx")) +// } +// tasks.named("clean") { +// dependsOn("cleanCmakeCache") +// } + repositories { mavenCentral() google() diff --git a/packages/react-native-worklets/android/fix-prefab.gradle b/packages/react-native-worklets/android/fix-prefab.gradle new file mode 100644 index 000000000000..ed5a128f8520 --- /dev/null +++ b/packages/react-native-worklets/android/fix-prefab.gradle @@ -0,0 +1,69 @@ +tasks.configureEach { task -> + // Make sure that we generate our prefab publication file only after having built the native library + // so that not a header publication file, but a full configuration publication will be generated, which + // will include the .so file + + def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/ + def matcher = task.name =~ prefabConfigurePattern + if (matcher.matches()) { + def variantName = matcher[0][1] + task.outputs.upToDateWhen { false } + task.dependsOn("externalNativeBuild${variantName}") + } +} + +afterEvaluate { + def abis = reactNativeArchitectures() + rootProject.allprojects.each { proj -> + + println "Processing project: ${proj.name} 1" + + if (proj === rootProject) return + + println "Processing project: ${proj.name} 2" + + def dependsOnThisLib = proj.configurations.any { config -> + { + if (proj.name == "react-native-reanimated") { + println config.name + println config.dependencies.name + } + return config.dependencies.any { dep -> + dep.group == project.group && dep.name == project.name + } + } + } + + println "Processing project: ${proj.name} dependsOnThisLib = ${dependsOnThisLib}" + + if (!dependsOnThisLib && proj != project) return + + println "Processing project: ${proj.name} 3" + + if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) { + return + } + + println "Processing project: ${proj.name} 4" + + def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants + // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to + // generate a libnameConfig.cmake file that will contain our native library (.so). + // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue + variants.all { variant -> + def variantName = variant.name + abis.each { abi -> + def searchDir = new File(proj.projectDir, ".cxx/${variantName}") + if (!searchDir.exists()) return + def matches = [] + searchDir.eachDir { randomDir -> + def prefabFile = new File(randomDir, "${abi}/prefab_config.json") + if (prefabFile.exists()) matches << prefabFile + } + matches.each { prefabConfig -> + prefabConfig.setLastModified(System.currentTimeMillis()) + } + } + } + } +} diff --git a/yarn.lock b/yarn.lock index de8b50d70886..d9230ae6768d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6964,6 +6964,13 @@ __metadata: languageName: node linkType: hard +"@react-native/gradle-plugin@patch:@react-native/gradle-plugin@npm%3A0.82.0#~/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch": + version: 0.82.0 + resolution: "@react-native/gradle-plugin@patch:@react-native/gradle-plugin@npm%3A0.82.0#~/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch::version=0.82.0&hash=60e1b9" + checksum: 10/493d986f2b23678dacd32a5e20a1c4b94e981b5d1abdf6fd35a9fb195b61900250dabb05d54e64af7e779c5b2e55cb96f431c16db0ba326ae8c0d43c5956616d + languageName: node + linkType: hard + "@react-native/js-polyfills@npm:0.79.6": version: 0.79.6 resolution: "@react-native/js-polyfills@npm:0.79.6" From 27f8807956163dcdf29e3b3cab21cbebeeb3c715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Mon, 24 Nov 2025 20:31:08 +0100 Subject: [PATCH 3/8] fix: Reanimated failing when using Worklets as a prefab --- ...-gradle-plugin-npm-0.82.0-10aedc0588.patch | 15 ++++++ .../android/build.gradle | 2 + .../android/fix-prefab.gradle | 53 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 .yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch create mode 100644 packages/react-native-worklets/android/fix-prefab.gradle diff --git a/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch b/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch new file mode 100644 index 000000000000..4a729e21a42f --- /dev/null +++ b/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch @@ -0,0 +1,15 @@ +diff --git a/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt b/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +index 890e61c007d5b3e0a9a69d37ef10e8aa3ce5c6b6..91acd7b2930fedb4eca2461ba99287721ca1f38f 100644 +--- a/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt ++++ b/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +@@ -80,7 +80,9 @@ class ReactPlugin : Plugin { + configureRepositories(project) + } + +- configureReactNativeNdk(project, extension) ++ if(!project.gradle.startParameter.taskNames.any { it.contains("clean") }) { ++ configureReactNativeNdk(project, extension) ++ } + configureBuildConfigFieldsForApp(project, extension) + configureDevServerLocation(project) + configureBackwardCompatibilityReactMap(project) diff --git a/packages/react-native-worklets/android/build.gradle b/packages/react-native-worklets/android/build.gradle index 2e5ad454afb1..61c565b3b26c 100644 --- a/packages/react-native-worklets/android/build.gradle +++ b/packages/react-native-worklets/android/build.gradle @@ -150,6 +150,8 @@ apply plugin: "com.android.library" apply plugin: "maven-publish" apply plugin: "de.undercouch.download" +apply from: "./fix-prefab.gradle" + android { compileSdkVersion safeExtGet("compileSdkVersion", 34) diff --git a/packages/react-native-worklets/android/fix-prefab.gradle b/packages/react-native-worklets/android/fix-prefab.gradle new file mode 100644 index 000000000000..fcf502a0ca48 --- /dev/null +++ b/packages/react-native-worklets/android/fix-prefab.gradle @@ -0,0 +1,53 @@ +tasks.configureEach { task -> + // Make sure that we generate our prefab publication file only after having built the native library + // so that not a header publication file, but a full configuration publication will be generated, which + // will include the .so file + + def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/ + def matcher = task.name =~ prefabConfigurePattern + if (matcher.matches()) { + def variantName = matcher[0][1] + task.outputs.upToDateWhen { false } + task.dependsOn("externalNativeBuild${variantName}") + } +} + +afterEvaluate { + def abis = reactNativeArchitectures() + rootProject.allprojects.each { proj -> + + if (proj === rootProject) return + + def dependsOnThisLib = proj.configurations.any { config -> + config.dependencies.any { dep -> + dep.group == project.group && dep.name == project.name + } + } + + if (!dependsOnThisLib && proj != project) return + + if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) { + return + } + + def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants + // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to + // generate a libnameConfig.cmake file that will contain our native library (.so). + // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue + variants.all { variant -> + def variantName = variant.name + abis.each { abi -> + def searchDir = new File(proj.projectDir, ".cxx/${variantName}") + if (!searchDir.exists()) return + def matches = [] + searchDir.eachDir { randomDir -> + def prefabFile = new File(randomDir, "${abi}/prefab_config.json") + if (prefabFile.exists()) matches << prefabFile + } + matches.each { prefabConfig -> + prefabConfig.setLastModified(System.currentTimeMillis()) + } + } + } + } +} From 96f41f689f56a67707845cfc36f10e148a5297ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Mon, 24 Nov 2025 20:39:47 +0100 Subject: [PATCH 4/8] chore: add RNGP fix --- package.json | 3 +++ .../android/CMakeLists.txt | 15 +++------------ yarn.lock | 7 +++++++ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 141335c03687..81b7447f4021 100644 --- a/package.json +++ b/package.json @@ -70,5 +70,8 @@ "react-native-builder-bob": "0.40.13", "shelljs": "0.10.0", "typescript": "5.8.3" + }, + "resolutions": { + "@react-native/gradle-plugin@npm:0.82.0": "patch:@react-native/gradle-plugin@npm%3A0.82.0#~/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch" } } diff --git a/packages/react-native-reanimated/android/CMakeLists.txt b/packages/react-native-reanimated/android/CMakeLists.txt index d4731e6c9e5b..3f87cab8570b 100644 --- a/packages/react-native-reanimated/android/CMakeLists.txt +++ b/packages/react-native-reanimated/android/CMakeLists.txt @@ -45,6 +45,7 @@ file(GLOB_RECURSE REANIMATED_ANDROID_CPP_SOURCES CONFIGURE_DEPENDS find_package(fbjni REQUIRED CONFIG) find_package(ReactAndroid REQUIRED CONFIG) +find_package(react-native-worklets REQUIRED CONFIG) add_library(reanimated SHARED ${REANIMATED_COMMON_CPP_SOURCES} ${REANIMATED_ANDROID_CPP_SOURCES}) @@ -69,8 +70,7 @@ target_include_directories( "${REACT_NATIVE_DIR}/ReactCommon/runtimeexecutor" "${REACT_NATIVE_DIR}/ReactCommon/jsiexecutor" "${REACT_NATIVE_DIR}/ReactCommon/react/renderer/graphics/platform/cxx" - "${REACT_NATIVE_WORKLETS_DIR}/Common/cpp" - "${REACT_NATIVE_WORKLETS_DIR}/android/src/main/cpp") +) set_target_properties(reanimated PROPERTIES LINKER_LANGUAGE CXX) @@ -80,15 +80,6 @@ else() set(BUILD_TYPE "release") endif() -add_library(worklets SHARED IMPORTED) - -set_target_properties( - worklets - PROPERTIES - IMPORTED_LOCATION - "${REACT_NATIVE_WORKLETS_DIR}/android/build/intermediates/cmake/${BUILD_TYPE}/obj/${ANDROID_ABI}/libworklets.so" -) - set_target_properties(reanimated PROPERTIES LINKER_LANGUAGE CXX) # remove dead code sections set_target_properties(reanimated PROPERTIES LINK_FLAGS "-Wl,--gc-sections") @@ -108,4 +99,4 @@ target_link_libraries( ReactAndroid::jsi fbjni::fbjni android - worklets) + react-native-worklets::worklets) diff --git a/yarn.lock b/yarn.lock index de8b50d70886..d9230ae6768d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6964,6 +6964,13 @@ __metadata: languageName: node linkType: hard +"@react-native/gradle-plugin@patch:@react-native/gradle-plugin@npm%3A0.82.0#~/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch": + version: 0.82.0 + resolution: "@react-native/gradle-plugin@patch:@react-native/gradle-plugin@npm%3A0.82.0#~/.yarn/patches/@react-native-gradle-plugin-npm-0.82.0-10aedc0588.patch::version=0.82.0&hash=60e1b9" + checksum: 10/493d986f2b23678dacd32a5e20a1c4b94e981b5d1abdf6fd35a9fb195b61900250dabb05d54e64af7e779c5b2e55cb96f431c16db0ba326ae8c0d43c5956616d + languageName: node + linkType: hard + "@react-native/js-polyfills@npm:0.79.6": version: 0.79.6 resolution: "@react-native/js-polyfills@npm:0.79.6" From 000b063621000dc1492570a96c65641db260864e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Mon, 1 Dec 2025 12:53:45 +0100 Subject: [PATCH 5/8] refactor(Worklets): remove public header dir --- docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx | 2 +- docs/docs-worklets/src/theme/TOCItems/index.js | 1 - .../Common/cpp/worklets/{Public => RunLoop}/AsyncQueue.h | 0 .../Common/cpp/worklets/RunLoop/AsyncQueueImpl.h | 2 +- .../Common/cpp/worklets/RunLoop/EventLoop.h | 2 +- .../Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h | 2 +- packages/react-native-worklets/src/runtimes.native.ts | 2 +- packages/react-native-worklets/src/types.ts | 4 ++-- 8 files changed, 7 insertions(+), 8 deletions(-) rename packages/react-native-worklets/Common/cpp/worklets/{Public => RunLoop}/AsyncQueue.h (100%) diff --git a/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx b/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx index 876f391cccc4..9e5bada9f5e5 100644 --- a/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx +++ b/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx @@ -48,7 +48,7 @@ Arguments to the function you want to execute on the [Worker Runtime](/docs/fund ## Remarks - The worklet is scheduled on the Worker Runtime's [Async - Queue](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h) + Queue](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h) - The worklet cannot be scheduled on the Worker Runtime from [UI Runtime](/docs/fundamentals/runtimeKinds#ui-runtime) or another [Worker Runtime](/docs/fundamentals/runtimeKinds#worker-runtime), unless the [Bundle Mode](/docs/experimental/bundleMode) is enabled. diff --git a/docs/docs-worklets/src/theme/TOCItems/index.js b/docs/docs-worklets/src/theme/TOCItems/index.js index 6ed752415171..4c3538b43bab 100644 --- a/docs/docs-worklets/src/theme/TOCItems/index.js +++ b/docs/docs-worklets/src/theme/TOCItems/index.js @@ -1,6 +1,5 @@ import { TOCItems } from '@swmansion/t-rex-ui'; - export default function TOCItemsWrapper(props) { return ( <> diff --git a/packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h similarity index 100% rename from packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h rename to packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h diff --git a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h index 30cd0d7a0292..72592049201b 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h +++ b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include diff --git a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/EventLoop.h b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/EventLoop.h index ac3eed1816d1..885bbbe2a8c1 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/RunLoop/EventLoop.h +++ b/packages/react-native-worklets/Common/cpp/worklets/RunLoop/EventLoop.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include diff --git a/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h b/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h index 919f0de2e95d..715c7009fa42 100644 --- a/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +++ b/packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include diff --git a/packages/react-native-worklets/src/runtimes.native.ts b/packages/react-native-worklets/src/runtimes.native.ts index 3443aa6e01b4..bca57ac5c157 100644 --- a/packages/react-native-worklets/src/runtimes.native.ts +++ b/packages/react-native-worklets/src/runtimes.native.ts @@ -115,7 +115,7 @@ export function createWorkletRuntime( * for more information about the different runtime kinds. * * - The worklet is scheduled on the Worker Runtime's [Async - * Queue](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h) + * Queue](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/Common/cpp/worklets/RunLoop/AsyncQueue.h) * - The function cannot be scheduled on the Worker Runtime from [UI * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds#ui-runtime) * or another [Worker diff --git a/packages/react-native-worklets/src/types.ts b/packages/react-native-worklets/src/types.ts index 916e175a4a1f..8a3f4859cbda 100644 --- a/packages/react-native-worklets/src/types.ts +++ b/packages/react-native-worklets/src/types.ts @@ -130,7 +130,7 @@ export type WorkletRuntimeConfig = { * An optional custom queue to be used for scheduling worklets. * * The queue has to implement the C++ `AsyncQueue` interface from - * ``. + * ``. */ customQueue?: never; } @@ -144,7 +144,7 @@ export type WorkletRuntimeConfig = { * An optional custom queue to be used for scheduling worklets. * * The queue has to implement the C++ `AsyncQueue` interface from - * ``. + * ``. */ customQueue?: object; } From 34130d3bba0f425cc7039a54fffa0a88113713b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Mon, 1 Dec 2025 12:59:38 +0100 Subject: [PATCH 6/8] chore: remove unused variable --- packages/react-native-reanimated/android/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-native-reanimated/android/build.gradle b/packages/react-native-reanimated/android/build.gradle index 86bace765ea9..c62f275012b1 100644 --- a/packages/react-native-reanimated/android/build.gradle +++ b/packages/react-native-reanimated/android/build.gradle @@ -198,7 +198,6 @@ android { "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}", "-DANDROID_TOOLCHAIN=clang", "-DREACT_NATIVE_DIR=${toPlatformFileString(reactNativeRootDir.path)}", - "-DREACT_NATIVE_WORKLETS_DIR=${toPlatformFileString(reactNativeWorkletsRootDir.path)}", "-DIS_REANIMATED_EXAMPLE_APP=${IS_REANIMATED_EXAMPLE_APP}", "-DREANIMATED_PROFILING=${REANIMATED_PROFILING}", "-DREANIMATED_VERSION=${REANIMATED_VERSION}", From 54aa8e89891bc96cc8ba3b788b6233f0d243dd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Mon, 1 Dec 2025 15:46:51 +0100 Subject: [PATCH 7/8] feat: linking --- apps/fabric-example/android/gradle.properties | 7 +- .../android/build.gradle | 25 ++-- .../android/CMakeLists.txt | 38 ----- .../android/build.gradle | 139 ++++++------------ 4 files changed, 65 insertions(+), 144 deletions(-) diff --git a/apps/fabric-example/android/gradle.properties b/apps/fabric-example/android/gradle.properties index dc802ce5753e..d183897bec8e 100644 --- a/apps/fabric-example/android/gradle.properties +++ b/apps/fabric-example/android/gradle.properties @@ -25,8 +25,7 @@ android.useAndroidX=true # Use this property to specify which architecture you want to build. # You can also override it from the CLI using # ./gradlew -PreactNativeArchitectures=x86_64 -# reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 -reactNativeArchitectures=arm64-v8a +reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 # Use this property to enable support to the new architecture. # This will allow you to use TurboModules and the Fabric render in @@ -53,5 +52,5 @@ enableReanimatedProfiling=true # workletsBundleMode=true # https://docs.gradle.org/current/userguide/configuration_cache.html -# org.gradle.configuration-cache=true -# org.gradle.configuration-cache.problems=fail +org.gradle.configuration-cache=true +org.gradle.configuration-cache.problems=fail diff --git a/packages/react-native-reanimated/android/build.gradle b/packages/react-native-reanimated/android/build.gradle index 6e0b3e53c70c..d1385dff4511 100644 --- a/packages/react-native-reanimated/android/build.gradle +++ b/packages/react-native-reanimated/android/build.gradle @@ -111,8 +111,6 @@ def getReanimatedStaticFeatureFlags() { return featureFlags.collect { key, value -> "[${key}:${value}]" }.join("") } -// apply from: "./fix-prefab.gradle" - if (isNewArchitectureEnabled()) { apply plugin: "com.facebook.react" } @@ -315,13 +313,22 @@ task prepareReanimatedHeadersForPrefabs(type: Copy) { into(reanimatedPrefabHeadersDir) } -// tasks.register("cleanCmakeCache", Delete) { -// delete(layout.projectDirectory.dir(".cxx")) -// delete(layout.projectDirectory.dir("build")) -// } -// tasks.named("clean") { -// dependsOn("cleanCmakeCache") -// } +interface FSService { + @Inject FileSystemOperations getFs() +} + +tasks.register('cleanCmakeCache', Delete) { + def fsService = project.objects.newInstance(FSService) + def projectDir = project.projectDir + doFirst { + fsService.fs.delete {"$projectDir/.cxx" + } + } +} + +tasks.named('clean') { + dependsOn cleanCmakeCache +} repositories { mavenCentral() diff --git a/packages/react-native-worklets/android/CMakeLists.txt b/packages/react-native-worklets/android/CMakeLists.txt index 6a8a81a8a960..acd96117cab8 100644 --- a/packages/react-native-worklets/android/CMakeLists.txt +++ b/packages/react-native-worklets/android/CMakeLists.txt @@ -60,19 +60,6 @@ endif() add_library(worklets SHARED ${WORKLETS_COMMON_CPP_SOURCES} ${WORKLETS_ANDROID_CPP_SOURCES}) -add_library( - RNWorklets - INTERFACE - "${COMMON_CPP_DIR}/worklets/RunLoop/AsyncQueue.h" - "${COMMON_CPP_DIR}/worklets/WorkletRuntime/WorkletRuntime.h" - "${COMMON_CPP_DIR}/worklets/SharedItems/Serializable.h" - "${COMMON_CPP_DIR}/worklets/SharedItems/Synchronizable.h") - -get_target_property(WORKLETS_TYPE worklets TYPE) -get_target_property(RNWORKLETS_TYPE RNWorklets TYPE) -message(WARNING "worklets library added, type: ${WORKLETS_TYPE}") -message(WARNING "RNWorklets library added, type: ${RNWORKLETS_TYPE}") - if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 80) include( "${REACT_NATIVE_DIR}/ReactCommon/cmake-utils/react-native-flags.cmake") @@ -119,28 +106,3 @@ if(${JS_RUNTIME} STREQUAL "hermes") elseif(${JS_RUNTIME} STREQUAL "jsc") target_link_libraries(worklets ReactAndroid::jsctooling) endif() - -# get_cmake_property(_variableNames VARIABLES) list(SORT _variableNames) -# foreach(_variableName ${_variableNames}) message(WARNING "${_variableName} = -# ${${_variableName}}") endforeach() - -# set(PUBLIC_INCLUDE_DIR "${RNWORKLETS_HEADERS_DIR}") - -# file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}") - -# # // // Pack public headers to RNWorklets headers dir // # -# from("$projectDir/../Common/cpp/worklets/RunLoop/") { // # -# include("AsyncQueue.h") // } // # -# from("$projectDir/../Common/cpp/worklets/WorkletRuntime/") { // # -# include("WorkletRuntime.h") // } // # -# from("$projectDir/../Common/cpp/worklets/SharedItems/") { // # -# include("Serializable.h") // include("Synchronizable.h") // } - -# file(CREATE_LINK "${COMMON_CPP_DIR}/worklets/RunLoop/AsyncQueue.h" -# "${PUBLIC_INCLUDE_DIR}/AsyncQueue.h" SYMBOLIC) file(CREATE_LINK -# "${COMMON_CPP_DIR}/worklets/WorkletRuntime/WorkletRuntime.h" -# "${PUBLIC_INCLUDE_DIR}/WorkletRuntime.h" SYMBOLIC) file(CREATE_LINK -# "${COMMON_CPP_DIR}/worklets/SharedItems/Serializable.h" -# "${PUBLIC_INCLUDE_DIR}/Serializable.h" SYMBOLIC) file(CREATE_LINK -# "${COMMON_CPP_DIR}/worklets/SharedItems/Synchronizable.h" -# "${PUBLIC_INCLUDE_DIR}/Synchronizable.h" SYMBOLIC) diff --git a/packages/react-native-worklets/android/build.gradle b/packages/react-native-worklets/android/build.gradle index aac2668dea09..e28f404be351 100644 --- a/packages/react-native-worklets/android/build.gradle +++ b/packages/react-native-worklets/android/build.gradle @@ -1,6 +1,7 @@ import com.android.build.gradle.tasks.ExternalNativeBuildJsonTask import groovy.json.JsonSlurper +import javax.inject.Inject import java.nio.file.Files import java.nio.file.Paths import org.apache.tools.ant.taskdefs.condition.Os @@ -109,19 +110,7 @@ def HERMES_V1_ENABLED = safeAppExtGet("hermesV1Enabled", false) // Set version for prefab version WORKLETS_VERSION -def workletsPrefabHeadersDir = project.file("${buildDir}/prefab-headers/worklets") -workletsPrefabHeadersDir.mkdirs() -def RNWorkletsPrefabHeadersDir = project.file("${buildDir}/prefab-headers/RNWorklets") -RNWorkletsPrefabHeadersDir.mkdirs() -def RNWorkletsPrefabHeadersAPIDir = project.file("${buildDir}/prefab-headers/RNWorklets/RNWorklets") -RNWorkletsPrefabHeadersAPIDir.mkdirs() -// def rootProjectBuildDir = rootProject.hasProperty("buildDir") ? rootProject.buildDir : "${rootProject.projectDir}/build" -// println("Root project build dir: ") -// println(rootProject) -// println(rootProject.hasProperty("buildDir")) -// println(rootProject.buildDir) -// println(rootProjectBuildDir) -// println(rootProject.projectDir) +def workletsPrefabHeadersDir = project.file("$buildDir/prefab-headers/worklets") def JS_RUNTIME = { // Override JS runtime with environment variable @@ -188,13 +177,6 @@ android { prefab { worklets { headers workletsPrefabHeadersDir.absolutePath - headerOnly false - // headers RNWorkletsPrefabHeadersDir.absolutePath - } - RNWorklets { - // headers RNWorkletsHeadersDir.absolutePath - headers RNWorkletsPrefabHeadersDir.absolutePath - headerOnly true } } @@ -222,10 +204,8 @@ android { "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON", "-DWORKLETS_FEATURE_FLAGS=${WORKLETS_FEATURE_FLAGS}", "-DHERMES_V1_ENABLED=${HERMES_V1_ENABLED}" - // , - // "-DRNWORKLETS_HEADERS_DIR=${toPlatformFileString(RNWorkletsHeadersDir.path)}" abiFilters (*reactNativeArchitectures()) - targets("worklets", "RNWorklets") + targets("worklets") } } @@ -335,90 +315,65 @@ task assertNewArchitectureEnabledTask { preBuild.dependsOn(assertNewArchitectureEnabledTask) -//tasks.register('prepareWorkletsHeadersForPrefabs',) { -task prepareWorkletsHeadersForPrefabs { - doFirst { - workletsPrefabHeadersDir.mkdirs() - RNWorkletsPrefabHeadersDir.mkdirs() - RNWorkletsPrefabHeadersAPIDir.mkdirs() - -// inputs.files(fileTree("$projectDir/src/main/cpp") { -// include '**/worklets/**/*.h' -// }) -// inputs.files(fileTree("$projectDir/../Common/cpp") { -// include '**/worklets/**/*.h' -// }) - // inputs.files([ - // file("$projectDir/../Common/cpp/worklets/RunLoop/AsyncQueue.h"), - // file("$projectDir/../Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h"), - // file("$projectDir/../Common/cpp/worklets/SharedItems/Serializable.h"), - // file("$projectDir/../Common/cpp/worklets/SharedItems/Synchronizable.h") - // ]) - - def sourceDir1 = file("$projectDir/src/main/cpp") - def sourceDir2 = file("$projectDir/../Common/cpp") - - [sourceDir1, sourceDir2].each { sourceDir -> - if (sourceDir.exists()) { - sourceDir.eachFileRecurse { sourceFile -> - if (sourceFile.isFile() && sourceFile.path.contains("worklets") && sourceFile.name.endsWith(".h")) { - def relativePath = sourceDir.toPath().relativize(sourceFile.toPath()) - def targetFile = file("${workletsPrefabHeadersDir}/${relativePath}") - - targetFile.parentFile.mkdirs() - - if (targetFile.exists()) { - targetFile.delete() - } - - Files.createSymbolicLink( - targetFile.toPath(), - sourceFile.toPath() - ) - } - } - } - } +task prepareWorkletsHeadersForPrefabs(type: Copy) { + from("$projectDir/src/main/cpp") + from("$projectDir/../Common/cpp") + include("worklets/**/*.h") + into(workletsPrefabHeadersDir) +} - def sourceFiles = [ - file("$projectDir/../Common/cpp/worklets/RunLoop/AsyncQueue.h"), - file("$projectDir/../Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h"), - file("$projectDir/../Common/cpp/worklets/SharedItems/Serializable.h"), - file("$projectDir/../Common/cpp/worklets/SharedItems/Synchronizable.h") - ] +def workletsPublicTargetDir = file("${workletsPrefabHeadersDir}/RNWorklets") + +tasks.register('cleanWorkletsHeaders', Delete) { + delete workletsPublicTargetDir +} - sourceFiles.each { sourceFile -> - def targetFile = file("${RNWorkletsPrefabHeadersAPIDir}/${sourceFile.name}") - targetFile.parentFile.mkdirs() +task preparePublicHeadersForPrefabs_experimental { + dependsOn prepareWorkletsHeadersForPrefabs + dependsOn cleanWorkletsHeaders - if (targetFile.exists()) { - targetFile.delete() - } + def links = [ + [file("${workletsPrefabHeadersDir}/worklets/WorkletRuntime/WorkletRuntime.h"), file("${workletsPublicTargetDir}/WorkletRuntime.h")], + [file("${workletsPrefabHeadersDir}/worklets/RunLoop/AsyncQueue.h"), file("${workletsPublicTargetDir}/AsyncQueue.h")], + [file("${workletsPrefabHeadersDir}/worklets/SharedItems/Serializable.h"), file("${workletsPublicTargetDir}/Serializable.h")], + [file("${workletsPrefabHeadersDir}/worklets/SharedItems/Synchronizable.h"), file("${workletsPublicTargetDir}/Synchronizable.h")] + ] - Files.createSymbolicLink( - targetFile.toPath(), - sourceFile.toPath() - ) + doLast { + workletsPublicTargetDir.mkdirs() + + links.each { link -> + Files.createSymbolicLink(link[1].toPath(), link[0].toPath()) } + } +} -// outputs.dir(workletsPrefabHeadersDir) -// outputs.dir(RNWorkletsPrefabHeadersDir) +interface FSService { + @Inject FileSystemOperations getFs() +} + +tasks.register('cleanCmakeCache', Delete) { + def fsService = project.objects.newInstance(FSService) + def projectDir = project.projectDir + doFirst { + fsService.fs.delete {"$projectDir/.cxx" + } } } -// tasks.register("cleanCmakeCache", Delete) { -// delete(layout.projectDirectory.dir(".cxx")) -// } -// tasks.named("clean") { -// dependsOn("cleanCmakeCache") -// } +tasks.named('clean') { + dependsOn cleanCmakeCache +} repositories { mavenCentral() google() } +preBuild.dependsOn(prepareWorkletsHeadersForPrefabs) +preBuild.dependsOn(preparePublicHeadersForPrefabs_experimental) + dependencies { implementation "com.facebook.yoga:proguard-annotations:1.19.0" implementation "androidx.transition:transition:1.1.0" @@ -429,5 +384,3 @@ dependencies { implementation "com.facebook.react:hermes-android" // version substituted by RNGP } } - -preBuild.dependsOn(prepareWorkletsHeadersForPrefabs) From 78098a469341ff25b0e2a875218dfc87feb01a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= Date: Tue, 2 Dec 2025 10:48:11 +0100 Subject: [PATCH 8/8] chore: cleanup --- .../android/fix-prefab.gradle | 51 ------------------- .../android/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 52 deletions(-) delete mode 100644 packages/react-native-reanimated/android/fix-prefab.gradle diff --git a/packages/react-native-reanimated/android/fix-prefab.gradle b/packages/react-native-reanimated/android/fix-prefab.gradle deleted file mode 100644 index d6c010ef785b..000000000000 --- a/packages/react-native-reanimated/android/fix-prefab.gradle +++ /dev/null @@ -1,51 +0,0 @@ -tasks.configureEach { task -> - // Make sure that we generate our prefab publication file only after having built the native library - // so that not a header publication file, but a full configuration publication will be generated, which - // will include the .so file - - def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/ - def matcher = task.name =~ prefabConfigurePattern - if (matcher.matches()) { - def variantName = matcher[0][1] - task.outputs.upToDateWhen { false } - task.dependsOn("externalNativeBuild${variantName}") - } -} - -afterEvaluate { - def abis = reactNativeArchitectures() - rootProject.allprojects.each { proj -> - if (proj === rootProject) return - - def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config -> - config.dependencies.any { dep -> - dep.group == project.group && dep.name == project.name - } - } - if (!dependsOnThisLib && proj != project) return - - if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) { - return - } - - def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants - // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to - // generate a libnameConfig.cmake file that will contain our native library (.so). - // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue - variants.all { variant -> - def variantName = variant.name - abis.each { abi -> - def searchDir = new File(proj.projectDir, ".cxx/${variantName}") - if (!searchDir.exists()) return - def matches = [] - searchDir.eachDir { randomDir -> - def prefabFile = new File(randomDir, "${abi}/prefab_config.json") - if (prefabFile.exists()) matches << prefabFile - } - matches.each { prefabConfig -> - prefabConfig.setLastModified(System.currentTimeMillis()) - } - } - } - } -} diff --git a/packages/react-native-worklets/android/CMakeLists.txt b/packages/react-native-worklets/android/CMakeLists.txt index acd96117cab8..7ce60581c4de 100644 --- a/packages/react-native-worklets/android/CMakeLists.txt +++ b/packages/react-native-worklets/android/CMakeLists.txt @@ -1,5 +1,5 @@ project(Worklets) -cmake_minimum_required(VERSION 3.13) +cmake_minimum_required(VERSION 3.8) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)