From 89de69613af89fb4db5d32d68ec29e0d4eb9ee9e Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Wed, 19 Mar 2025 07:55:32 -0700 Subject: [PATCH] Build JSI, React-Debug, React-logger, React-MapBuffer with SPM (#50075) Summary: This is an exploratory change to see how it will look like to build core from SPM. In this change we are building three pieces of React native (using the Podspec names for simplicity): - React-jsi - React-debug - React-logger - React-MapBuffer They depends on a local ReactNativeDependency.xcframework we can build using the prebuild-io script. ## CHANGELOG: [INTERNAL] - set up initial Swift PM configuration Reviewed By: cortinico Differential Revision: D70567840 --- packages/react-native/Package.swift | 111 ++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 packages/react-native/Package.swift diff --git a/packages/react-native/Package.swift b/packages/react-native/Package.swift new file mode 100644 index 00000000000000..61ba5abe20bd2b --- /dev/null +++ b/packages/react-native/Package.swift @@ -0,0 +1,111 @@ +// swift-tools-version: 6.0 +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import PackageDescription + +let react = "React" + +let cxxRNDepHeaderSearchPath: (Int) -> CXXSetting = { + let prefix = (0..<$0).map { _ in "../" } .joined(separator: "") + return .headerSearchPath("\(prefix)third-party/ReactNativeDependencies.xcframework/Headers") +} +let cRNDepHeaderSearchPath: (Int) -> CSetting = { + let prefix = (0..<$0).map { _ in "../" } .joined(separator: "") + return .headerSearchPath("\(prefix)third-party/ReactNativeDependencies.xcframework/Headers") +} + +let package = Package( + name: react, + products: [ + .library( + name: react, + type: .dynamic, + targets: [.reactDebug, .jsi, .logger, .mapbuffer] + ), + ], + targets: [ + .reactNativeTarget( + name: .reactDebug, + dependencies: [.reactNativeDependencies], + path: "ReactCommon/react/debug", + publicHeadersPath: "." + ), + .reactNativeTarget( + name: .jsi, + dependencies: [.reactNativeDependencies], + path: "ReactCommon/jsi", + extraExcludes: ["jsi/CMakeLists.txt", "jsi/test/testlib.h", "jsi/test/testlib.cpp"], + sources: ["jsi"], + publicHeadersPath: "jsi/", + extraCSettings: [.headerSearchPath(".")], + extraCxxSettings: [.headerSearchPath(".")] + ), + .reactNativeTarget( + name: .logger, + dependencies: [.reactNativeDependencies, .jsi], + path: "ReactCommon/logger", + publicHeadersPath: "." + ), + .reactNativeTarget( + name: .mapbuffer, + dependencies: [.reactNativeDependencies, .reactDebug], + path: "ReactCommon/react/renderer/mapbuffer", + extraExcludes: ["tests/MapBufferTest.cpp"], + publicHeadersPath: ".", + extraCSettings: [.headerSearchPath("../../..")], + extraCxxSettings: [.headerSearchPath("../../..")] + ), + .binaryTarget( + name: .reactNativeDependencies, + path: "third-party/ReactNativeDependencies.xcframework" + ), + ] +) + +extension String { + static let reactDebug = "React-debug" + static let jsi = "React-jsi" + static let logger = "React-logger" + static let mapbuffer = "React-Mapbuffer" + + static let reactNativeDependencies = "ReactNativeDependencies" +} + +func defaultExcludeFor(module: String) -> [String] { + return ["BUCK", "CMakeLists.txt", "\(module).podspec"] +} + +extension Target { + static func reactNativeTarget( + name: String, + dependencies: [String], + path: String, + extraExcludes: [String] = [], + sources: [String]? = nil, + publicHeadersPath: String? = nil, + extraCSettings: [CSetting] = [], + extraCxxSettings: [CXXSetting] = [] + ) -> Target { + let dependencies = dependencies.map { Dependency.byNameItem(name: $0, condition: nil) } + let excludes = defaultExcludeFor(module: .logger) + extraExcludes + let numOfSlash = path.count { $0 == "/" } + let cSettings = [cRNDepHeaderSearchPath(numOfSlash + 1)] + extraCSettings + let cxxSettings = [cxxRNDepHeaderSearchPath(numOfSlash + 1), .unsafeFlags(["-std=c++20"])] + extraCxxSettings + + return .target( + name: name, + dependencies: dependencies, + path: path, + exclude: excludes, + sources: sources, + publicHeadersPath: publicHeadersPath, + cSettings: cSettings, + cxxSettings: cxxSettings + ) + } +}