From cf89c1758bcb762e9cfad4cad59ef0eceb64232a Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Mon, 13 Oct 2025 10:11:26 -0700 Subject: [PATCH] Configure Package.swift file to be able to build from source (#53667) Summary: This change updates the Package.swift file to enable building RNTester and HelloWorld from source. The set of changes is the following: - add a BUILD_FROM_SOURCE flag to toggle between building for creating prebuilds and building an app from source - configure the proper header search path based on whether we want to build an app from source or not - split the ReactFabricComponents target in multiple subtargets. This is required because when building from source we can't have targets whose Source folder is overlapping. ## Changelog: [Internal] - Reviewed By: cortinico Differential Revision: D81778452 --- packages/react-native/Package.swift | 129 +++++++++++++++++++++------- 1 file changed, 98 insertions(+), 31 deletions(-) diff --git a/packages/react-native/Package.swift b/packages/react-native/Package.swift index 83eaf65fe535..db484e886d4e 100644 --- a/packages/react-native/Package.swift +++ b/packages/react-native/Package.swift @@ -6,8 +6,11 @@ * LICENSE file in the root directory of this source tree. */ +import Foundation import PackageDescription +let BUILD_FROM_SOURCE = false + /** This is the `Package.swift` file that allows to build React Native core using Swift PM. To build React Native, you need to follow these steps: @@ -33,6 +36,8 @@ let RuntimeExecutorPath = "ReactCommon/runtimeexecutor" // header only target let CallInvokerPath = "ReactCommon/callinvoker" // header only target let ReactFBReactNativeSpecPath = "React/FBReactNativeSpec" // generated let FBLazyVectorPath = "Libraries/FBLazyVector" // header only +let virtualViewPath = "ReactCommon/react/renderer/components/virtualview" // header only +let virtualViewExperimentalPath = "ReactCommon/react/renderer/components/virtualviewexperimental" // header only // MARK: Prebuilt Dependencies declaration let reactNativeDependencies = BinaryTarget( @@ -391,6 +396,8 @@ let reactRuntimeApple = RNTarget( dependencies: [.reactNativeDependencies, .jsi, .reactPerfLogger, .reactCxxReact, .rctDeprecation, .yoga, .reactRuntime, .reactRCTFabric, .reactCoreModules, .reactTurboModuleCore, .hermesPrebuilt, .reactUtils] ) +let publicHeadersPathForReactCore: String = BUILD_FROM_SOURCE ? "includes" : "." + /// React-Core.podspec let reactCore = RNTarget( name: .reactCore, @@ -403,7 +410,8 @@ let reactCore = RNTarget( linkedFrameworks: ["CoreServices"], excludedPaths: ["Fabric", "Tests", "Resources", "Runtime/RCTJscInstanceFactory.mm", "I18n/strings", "CxxBridge/JSCExecutorFactory.mm", "CoreModules"], dependencies: [.reactNativeDependencies, .reactCxxReact, .reactPerfLogger, .jsi, .reactJsiExecutor, .reactUtils, .reactFeatureFlags, .reactRuntimeScheduler, .yoga, .reactJsInspector, .reactJsiTooling, .rctDeprecation, .reactCoreRCTWebsocket, .reactRCTImage, .reactTurboModuleCore, .reactRCTText, .reactRCTBlob, .reactRCTAnimation, .reactRCTNetwork, .reactFabric, .hermesPrebuilt], - sources: [".", "Runtime/RCTHermesInstanceFactory.mm"] + sources: [".", "Runtime/RCTHermesInstanceFactory.mm"], + publicHeadersPath: publicHeadersPathForReactCore ) /// React-Fabric.podspec @@ -434,6 +442,7 @@ let reactFabric = RNTarget( "components/modal", "components/rncore", "components/safeareaview", + "components/switch", "components/text", "components/textinput", "components/textinput/platform/ios/", @@ -446,37 +455,66 @@ let reactFabric = RNTarget( sources: ["animations", "attributedstring", "core", "componentregistry", "componentregistry/native", "components/root", "components/view", "components/view/platform/cxx", "components/scrollview", "components/scrollview/platform/cxx", "components/legacyviewmanagerinterop", "dom", "scheduler", "mounting", "observers/events", "telemetry", "consistency", "leakchecker", "uimanager", "uimanager/consistency"] ) -/// React-RCTFabric.podspec -let reactRCTFabric = RNTarget( - name: .reactRCTFabric, - path: "React/Fabric", - dependencies: [.reactNativeDependencies, .reactCore, .reactRCTImage, .yoga, .reactRCTText, .jsi, .reactFabricComponents, .reactGraphics, .reactImageManager, .reactDebug, .reactUtils, .reactPerformanceTimeline, .reactRendererDebug, .reactRendererConsistency, .reactRuntimeScheduler, .reactRCTAnimation, .reactJsInspector, .reactJsInspectorNetwork, .reactJsInspectorTracing, .reactFabric, .reactFabricImage, .rctSwiftUIWrapper] +let reactFabricInputAccessory = RNTarget( + name: .reactFabricInputAccessory, + path: "ReactCommon/react/renderer/components/inputaccessory", + dependencies: [.reactNativeDependencies, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactFabric, .reactTurboModuleBridging] ) -/// React-FabricComponents.podspec -let reactFabricComponents = RNTarget( - name: .reactFabricComponents, - path: "ReactCommon/react/renderer", +let reactFabricModal = RNTarget( + name: .reactFabricModal, + path: "ReactCommon/react/renderer/components/modal", excludedPaths: [ - "components/modal/platform/android", - "components/modal/platform/cxx", - "components/view/platform/android", - "components/view/platform/windows", - "components/view/platform/macos", - "components/switch/iosswitch/react/renderer/components/switch/MacOSSwitchShadowNode.mm", - "components/textinput/platform/android", - "components/text/platform/android", - "components/textinput/platform/macos", - "components/text/tests", - "textlayoutmanager/tests", - "textlayoutmanager/platform/android", - "textlayoutmanager/platform/cxx", - "textlayoutmanager/platform/windows", - "textlayoutmanager/platform/macos", - "conponents/rncore", // this was the old folder where RN Core Components were generated. If you ran codegen in the past, you might have some files in it that might make the build fail. + "platform/android", + "platform/cxx", + ], + dependencies: [.reactNativeDependencies, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactFabric, .reactTurboModuleBridging] +) + +let reactFabricSwitch = RNTarget( + name: .reactFabricSwitch, + path: "ReactCommon/react/renderer/components/switch/iosswitch", + excludedPaths: ["react/renderer/components/switch/MacOSSwitchShadowNode.mm"], + dependencies: [.reactNativeDependencies, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactFabric, .reactTurboModuleBridging] +) + +let reactFabricSafeAreaView = RNTarget( + name: .reactFabricSafeAreaView, + path: "ReactCommon/react/renderer/components/safeareaview", + dependencies: [.reactNativeDependencies, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactFabric, .reactTurboModuleBridging] +) + +let reactFabricTextLayoutManager = RNTarget( + name: .reactFabricTextLayoutManager, + path: "ReactCommon/react/renderer/textlayoutmanager", + excludedPaths: [ + "platform/android", + "platform/cxx", + "platform/windows", + "platform/macos", + "tests", ], dependencies: [.reactNativeDependencies, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactFabric, .reactTurboModuleBridging], - sources: ["components/inputaccessory", "components/modal", "components/safeareaview", "components/text", "components/text/platform/cxx", "components/textinput", "components/textinput/platform/ios/", "components/unimplementedview", "components/virtualview", "components/virtualviewexperimental", "textlayoutmanager", "textlayoutmanager/platform/ios", "components/switch/iosswitch"] + sources: [".", "platform/ios"] +) + +let reactFabricText = RNTarget( + name: .reactFabricText, + path: "ReactCommon/react/renderer/components/text", + excludedPaths: [ + "platform/android", + "tests", + ], + dependencies: [.reactNativeDependencies, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactFabric, .reactTurboModuleBridging, .reactFabricTextLayoutManager], + sources: [".", "platform/cxx"] +) + +let reactFabricTextInput = RNTarget( + name: .reactFabricTextInput, + path: "ReactCommon/react/renderer/components/textinput", + excludedPaths: ["platform/android", "platform/macos"], + dependencies: [.reactNativeDependencies, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactFabric, .reactTurboModuleBridging, .reactFabricTextLayoutManager], + sources: [".", "platform/ios"] ) /// React-FabricImage.podspec @@ -487,6 +525,20 @@ let reactFabricImage = RNTarget( dependencies: [.reactNativeDependencies, .reactFabric, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactTurboModuleBridging, .reactImageManagerApple] ) +let reactFabricUnimplementedView = RNTarget( + name: .reactFabricUnimplementedView, + path: "ReactCommon/react/renderer/components/unimplementedview", + dependencies: [.reactNativeDependencies, .reactCore, .reactJsiExecutor, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .yoga, .reactRendererDebug, .reactGraphics, .reactFabric, .reactTurboModuleBridging] +) + +/// React-RCTFabric.podspec +let reactRCTFabric = RNTarget( + name: .reactRCTFabric, + path: "React/Fabric", + searchPaths: [virtualViewPath, virtualViewExperimentalPath], + dependencies: [.reactNativeDependencies, .reactCore, .reactRCTImage, .yoga, .reactRCTText, .jsi, .reactFabricInputAccessory, .reactFabricModal, .reactFabricSafeAreaView, .reactFabricSwitch, .reactFabricText, .reactFabricTextInput, .reactFabricUnimplementedView, .reactFabricTextLayoutManager, .reactGraphics, .reactImageManager, .reactDebug, .reactUtils, .reactPerformanceTimeline, .reactRendererDebug, .reactRendererConsistency, .reactRuntimeScheduler, .reactRCTAnimation, .reactJsInspector, .reactJsInspectorNetwork, .reactJsInspectorTracing, .reactFabric, .reactFabricImage, .rctSwiftUIWrapper] +) + /// React-ImageManagerApple.podspec let reactImageManagerApple = RNTarget( name: .reactImageManagerApple, @@ -593,8 +645,15 @@ let targets = [ rctSwiftUI, rctSwiftUIWrapper, reactRCTFabric, - reactFabricComponents, reactFabricImage, + reactFabricInputAccessory, + reactFabricModal, + reactFabricSafeAreaView, + reactFabricSwitch, + reactFabricTextLayoutManager, + reactFabricText, + reactFabricTextInput, + reactFabricUnimplementedView, reactNativeDependencies, hermesPrebuilt, reactJsiTooling, @@ -762,12 +821,20 @@ extension String { static let reactJsInspector = "React-jsinspector" static let reactJsInspectorTracing = "React-jsinspectortracing" static let reactCxxReact = "React-cxxreact" - static let reactCore = "React-Core" - static let reactCoreRCTWebsocket = "React-Core/RCTWebSocket" + static let reactCore = "React" + static let reactCoreRCTWebsocket = "React/RCTWebSocket" static let reactFabric = "React-Fabric" static let reactRCTFabric = "React-RCTFabric" - static let reactFabricComponents = "React-FabricComponents" + static let reactFabricImage = "React-FabricImage" + static let reactFabricInputAccessory = "React-FabricInputAccessory" + static let reactFabricModal = "React-FabricModal" + static let reactFabricSafeAreaView = "React-FabricSafeAreaView" + static let reactFabricSwitch = "React-FabricSwitch" + static let reactFabricTextLayoutManager = "React-FabricTextLayoutManager" + static let reactFabricText = "React-FabricText" + static let reactFabricTextInput = "React-FabricTextInput" + static let reactFabricUnimplementedView = "React-FabricUnimplementedView" static let reactNativeDependencies = "ReactNativeDependencies"