diff --git a/packages/react-native/React-Core-prebuilt.podspec b/packages/react-native/React-Core-prebuilt.podspec new file mode 100644 index 00000000000000..0e5281b7aa753f --- /dev/null +++ b/packages/react-native/React-Core-prebuilt.podspec @@ -0,0 +1,109 @@ +# 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. + +require "json" + +package = JSON.parse(File.read(File.join(__dir__, "package.json"))) +version = package['version'] + +source = ReactNativeCoreUtils.resolve_podspec_source() + +header_search_paths = [ + "${PODS_ROOT}/Headers/Private/React-Core-prebuilt", + "${PODS_ROOT}/Headers/Private/React-Core-prebuilt/RCTDeprecation", + "${PODS_ROOT}/Headers/Private/React-Core-prebuilt/ReactCommon/yoga", + "${PODS_ROOT}/Headers/Private/React-Core-prebuilt/ReactCommon", + "${PODS_ROOT}/Headers/Private/React-Core-prebuilt/Libraries/AppDelegate", + "${PODS_ROOT}/Headers/Private/React-Core-prebuilt/Libraries", + + "$(REACT_NATIVE_PATH)/React/Base", + "$(REACT_NATIVE_PATH)/ReactCommon", + "$(REACT_NATIVE_PATH)/Libraries", + "$(REACT_NATIVE_PATH)/ReactApple", + "$(REACT_NATIVE_PATH)/ReactCxxPlatform", + "$(REACT_NATIVE_PATH)/ReactCommon/react/runtime/platform/ios", + "${REACT_NATIVE_PATH}/ReactCommon/jsi", + "$(REACT_NATIVE_PATH)/ReactCommon/jsiexecutor/", + "$(REACT_NATIVE_PATH)/ReactCommon/react/nativemodule/samples/platform/ios", + "$(REACT_NATIVE_PATH)/ReactCommon/react/nativemodule/samples", +] + +Pod::Spec.new do |spec| + spec.name = 'React-Core-prebuilt' + spec.version = version + spec.summary = "Prebuilt core of React Native." + spec.homepage = "https://reactnative.dev/" + spec.description = 'Prebuilt React Native Core libraries and headers' + spec.homepage = 'https://github.com/facebook/react-native' + spec.license = package['license'] + spec.authors = 'meta' + spec.platforms = min_supported_versions + spec.source = source + + spec.vendored_frameworks = "React.xcframework" + + spec.preserve_paths = '**/*.*' + spec.header_mappings_dir = 'React.xcframework/Headers' + spec.source_files = 'React.xcframework/Headers/**/*.{h,hpp}' + + spec.module_name = 'React' + spec.module_map = 'React.xcframework/Modules/module.modulemap' + spec.public_header_files = 'React.xcframework/Headers/**/*.h' + + # Setup the consuming project's search paths + spec.user_target_xcconfig = { + "HEADER_SEARCH_PATHS" => header_search_paths, + "SWIFT_INCLUDE_PATHS" => "${PODS_ROOT}/Headers/Private/React-Core-prebuilt", + 'DEFINES_MODULE' => 'YES', + 'CLANG_ENABLE_MODULES' => 'YES', + } + + spec.pod_target_xcconfig = { + 'WARNING_CFLAGS' => '-Wno-comma -Wno-shorten-64-to-32', + "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), + 'DEFINES_MODULE' => 'YES', + 'CLANG_ENABLE_MODULES' => 'YES', + } + + # We need to make sure that the React.xcframework is copied correctly - in the downloaded tarball + # the root directory is the framework, but when using it we need to have it in a subdirectory + # called React.xcframework, so we need to move the contents of the tarball into that directory. + # This is done in the prepare_command. + spec.prepare_command = <<~'CMD' + CURRENT_PATH=$(pwd) + XCFRAMEWORK_PATH="${CURRENT_PATH}/React.xcframework" + mkdir -p "${XCFRAMEWORK_PATH}" + find "$CURRENT_PATH" -mindepth 1 -maxdepth 1 ! -name "$(basename "$XCFRAMEWORK_PATH")" -exec mv {} "$XCFRAMEWORK_PATH" \; + CMD + + # If we are passing a local tarball, we don't want to switch between Debug and Release + if !ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"] + script_phase = { + :name => "[RNDeps] Replace React Native Core for the right configuration, if needed", + :execution_position => :before_compile, + :script => <<-EOS + . "$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh" + + CONFIG="Release" + if echo $GCC_PREPROCESSOR_DEFINITIONS | grep -q "DEBUG=1"; then + CONFIG="Debug" + fi + + # TODO(T228219721): Add this for React Native Core as well + ##### "$NODE_BINARY" "$REACT_NATIVE_PATH/third-party-podspecs/replace_dependencies_version.js" -c "$CONFIG" -r "#{version}" -p "$PODS_ROOT" + EOS + } + + + # :always_out_of_date is only available in CocoaPods 1.13.0 and later + if Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.13.0') + # always run the script without warning + script_phase[:always_out_of_date] = "1" + end + + spec.script_phase = script_phase + end + +end diff --git a/packages/react-native/scripts/cocoapods/rncore.rb b/packages/react-native/scripts/cocoapods/rncore.rb new file mode 100644 index 00000000000000..45fabb52ab5e39 --- /dev/null +++ b/packages/react-native/scripts/cocoapods/rncore.rb @@ -0,0 +1,220 @@ +# 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. + +require 'json' +require 'net/http' +require 'rexml/document' + +require_relative './utils.rb' + +## - RCT_USE_PREBUILT_RNCORE: If set to 1, it will use the release tarball from Maven instead of building from source. +## - RCT_TESTONLY_RNCORE_TARBALL_PATH: **TEST ONLY** If set, it will use a local tarball of RNCore if it exists. +## - RCT_TESTONLY_RNCORE_VERSION: **TEST ONLY** If set, it will override the version of RNCore to be used. + +class ReactNativeCoreUtils + @@build_from_source = true + @@react_native_path = "" + @@react_native_version = "" + @@use_nightly = false + + ## Sets up wether ReactNative Core should be built from source or not. + ## If RCT_USE_PREBUILT_RNCORE is set to 1 and the artifacts exists on Maven, it will + ## not build from source. Otherwise, it will build from source. + def self.setup_rncore(react_native_path, react_native_version) + # We don't want setup to be called multiple times, so we check if the variables are already set. + if @@react_native_version == "" + rncore_log("Setting up ReactNativeCore...") + @@react_native_path = react_native_path + @@react_native_version = ENV["RCT_TESTONLY_RNCORE_VERSION"] == nil ? react_native_version : ENV["RCT_TESTONLY_RNCORE_VERSION"] + + if @@react_native_version.include? "nightly" + @@use_nightly = true + if ENV["RCT_TESTONLY_RNCORE_VERSION"] == "nightly" + @@react_native_version = ReactNativeDependenciesUtils.get_nightly_npm_version() + rncore_log("Using nightly version from npm: #{@@react_native_version}") + else + rncore_log("Using nightly build #{@@react_native_version}") + end + end + + if ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"] + abort_if_use_local_rncore_with_no_file() + end + + use_local_xcframework = ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"] && File.exist?(ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"]) + artifacts_exists = ENV["RCT_USE_PREBUILT_RNCORE"] == "1" && (@@use_nightly ? nightly_artifact_exists(@@react_native_version) : release_artifact_exists(@@react_native_version)) + @@build_from_source = !use_local_xcframework && !artifacts_exists + + if @@build_from_source && ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"] && !use_local_xcframework + rncore_log("No local xcframework found, reverting to building from source.") + end + if @@build_from_source && ENV["RCT_USE_PREBUILT_RNCORE"] && !artifacts_exists + rncore_log("No prebuilt artifacts found, reverting to building from source.") + end + rncore_log("Building from source: #{@@build_from_source}") + rncore_log("Source: #{self.resolve_podspec_source()}") + end + end + + def self.abort_if_use_local_rncore_with_no_file() + if !File.exist?(ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"]) + abort("RCT_TESTONLY_RNCORE_TARBALL_PATH is set to #{ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"]} but the file does not exist!") + end + end + + def self.build_rncore_from_source() + return @@build_from_source + end + + def self.resolve_podspec_source() + if ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"] + abort_if_use_local_rncore_with_no_file() + rncore_log("Using local xcframework at #{ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"]}") + return {:http => "file://#{ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"]}" } + end + + if ENV["RCT_USE_PREBUILT_RNCORE"] == "1" + if @@use_nightly + rncore_log("Using nightly tarball") + begin + return self.podspec_source_download_prebuilt_nightly_tarball(@@react_native_version) + rescue => e + rncore_log("Failed to download nightly tarball: #{e.message}", :error) + return + end + end + + begin + return self.podspec_source_download_prebuild_stable_tarball() + rescue => e + rncore_log("Failed to download release tarball: #{e.message}", :error) + return + end + end + + end + + def self.podspec_source_download_prebuild_stable_tarball() + if @@react_native_path == "" + rncore_log("react_native_path is not set", :error) + return + end + + if @@react_native_version == "" + rncore_log("react_native_version is not set", :error) + return + end + + if @@build_from_source + return + end + + url = stable_tarball_url(@@react_native_version, :debug) + rncore_log("Using tarball from URL: #{url}") + download_stable_rndeps(@@react_native_path, @@react_native_version, :debug) + download_stable_rndeps(@@react_native_path, @@react_native_version, :release) + return {:http => url} + end + + def self.stable_tarball_url(version, build_type) + maven_repo_url = "https://repo1.maven.org/maven2" + group = "com/facebook/react" + # Sample url from Maven: + # https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.0/react-native-artifacts-0.81.0-reactnative-core-debug.tar.gz + return "#{maven_repo_url}/#{group}/react-native-artifacts/#{version}/react-native-artifacts-#{version}-reactnative-core-#{build_type.to_s}.tar.gz" + end + + def self.nightly_tarball_url(version) + artefact_coordinate = "react-native-artifacts" + artefact_name = "reactnative-core-debug.tar.gz" + xml_url = "https://central.sonatype.com/repository/maven-snapshots/com/facebook/react/#{artefact_coordinate}/#{version}-SNAPSHOT/maven-metadata.xml" + + response = Net::HTTP.get(URI(xml_url)) + if response.kind_of? Net::HTTPSuccess + xml = REXML::Document.new(response) + timestamp = xml.elements['metadata/versioning/snapshot/timestamp'].text + build_number = xml.elements['metadata/versioning/snapshot/buildNumber'].text + full_version = "#{version}-#{timestamp}-#{build_number}" + + final_url = "https://central.sonatype.com/repository/maven-snapshots/com/facebook/react/#{artefact_coordinate}/#{version}-SNAPSHOT/#{artefact_coordinate}-#{full_version}-#{artefact_name}" + return final_url + else + return "" + end + end + + def self.download_stable_rndeps(react_native_path, version, configuration) + tarball_url = stable_tarball_url(version, configuration) + download_rndeps_tarball(react_native_path, tarball_url, version, configuration) + end + + def self.podspec_source_download_prebuilt_nightly_tarball(version) + url = nightly_tarball_url(version) + rncore_log("Using nightly tarball from URL: #{url}") + return {:http => url} + end + + def self.download_rndeps_tarball(react_native_path, tarball_url, version, configuration) + destination_path = configuration == nil ? + "#{artifacts_dir()}/reactnative-core-debug.tar.gz-#{version}.tar.gz" : + "#{artifacts_dir()}/reactnative-core-debug.tar.gz-#{version}-#{configuration}.tar.gz" + + unless File.exist?(destination_path) + # Download to a temporary file first so we don't cache incomplete downloads. + tmp_file = "#{artifacts_dir()}/reactnative-core-debug.tar.gz.download" + `mkdir -p "#{artifacts_dir()}" && curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"` + end + + return destination_path + end + + def self.release_artifact_exists(version) + return artifact_exists(stable_tarball_url(version, :debug)) + end + + def self.nightly_artifact_exists(version) + return artifact_exists(nightly_tarball_url(version).gsub("\\", "")) + end + + def self.artifacts_dir() + return File.join(Pod::Config.instance.project_pods_root, "ReactNativeCore-artifacts") + end + + # This function checks that ReactNativeCore artifact exists on the maven repo + def self.artifact_exists(tarball_url) + # -L is used to follow redirects, useful for the nightlies + # I also needed to wrap the url in quotes to avoid escaping & and ?. + return (`curl -o /dev/null --silent -Iw '%{http_code}' -L "#{tarball_url}"` == "200") + end + + def self.rncore_log(message, level = :info) + if !Object.const_defined?("Pod::UI") + return + end + log_message = '[ReactNativeCore] ' + message + case level + when :info + Pod::UI.puts log_message.green + when :error + Pod::UI.puts log_message.red + else + Pod::UI.puts log_message.yellow + end + end + + def self.get_nightly_npm_version() + uri = URI('https://registry.npmjs.org/react-native/nightly') + response = Net::HTTP.get_response(uri) + + unless response.is_a?(Net::HTTPSuccess) + raise "Couldn't get an answer from NPM: #{response.code} #{response.message}" + end + + json = JSON.parse(response.body) + latest_nightly = json['version'] + return latest_nightly + end + +end diff --git a/packages/react-native/scripts/cocoapods/rndependencies.rb b/packages/react-native/scripts/cocoapods/rndependencies.rb index e102f7fe4e4311..253205536e9063 100644 --- a/packages/react-native/scripts/cocoapods/rndependencies.rb +++ b/packages/react-native/scripts/cocoapods/rndependencies.rb @@ -67,46 +67,78 @@ def self.build_react_native_deps_from_source() end def self.resolve_podspec_source() + if ENV["RCT_USE_LOCAL_RN_DEP"] + abort_if_use_local_rndeps_with_no_file() + rndeps_log("Using local xcframework at #{ENV["RCT_USE_LOCAL_RN_DEP"]}") + return {:http => "file://#{ENV["RCT_USE_LOCAL_RN_DEP"]}" } + end + if ENV["RCT_USE_RN_DEP"] && ENV["RCT_USE_RN_DEP"] == "1" if @@use_nightly rndeps_log("Using nightly tarball") - return self.podspec_source_download_prebuilt_nightly_tarball(@@react_native_version) + begin + return self.podspec_source_download_prebuilt_nightly_tarball(@@react_native_version) + rescue => e + rndeps_log("Failed to download nightly tarball: #{e.message}", :error) + return + end end rndeps_log("Using release tarball") - return self.podspec_source_download_prebuild_release_tarball() + begin + return self.podspec_source_download_prebuild_release_tarball() + rescue => e + rndeps_log("Failed to download release tarball: #{e.message}", :error) + return + end end - if ENV["RCT_USE_LOCAL_RN_DEP"] && File.exist?(ENV["RCT_USE_LOCAL_RN_DEP"]) - rndeps_log("Using local xcframework at #{ENV["RCT_USE_LOCAL_RN_DEP"]}") - return {:http => "file://#{ENV["RCT_USE_LOCAL_RN_DEP"]}" } - end end ## Sets up wether react-native-dependencies should be built from source or not. ## If RCT_USE_RN_DEP is set to 1 and the artifacts exists on Maven, it will ## not build from source. Otherwise, it will build from source. def self.setup_react_native_dependencies(react_native_path, react_native_version) - @@react_native_path = react_native_path - @@react_native_version = ENV["RCT_DEPS_VERSION"] == nil ? react_native_version : ENV["RCT_DEPS_VERSION"] + # We don't want setup to be called multiple times, so we check if the variables are already set. + if @@react_native_version == "" + rndeps_log("Setting up ReactNativeDependencies...") + @@react_native_path = react_native_path + @@react_native_version = ENV["RCT_DEPS_VERSION"] == nil ? react_native_version : ENV["RCT_DEPS_VERSION"] + + if @@react_native_version.include? 'nightly' + @@use_nightly = true + if ENV["RCT_DEPS_VERSION"] == "nightly" + @@react_native_version = ReactNativeDependenciesUtils.get_nightly_npm_version() + rndeps_log("Using nightly version from npm: #{@@react_native_version}") + else + rndeps_log("Using nightly build #{@@react_native_version}") + end + end - if @@react_native_version.include? 'nightly' - rndeps_log("Using nightly build") - @@use_nightly = true - end + if ENV["RCT_USE_LOCAL_RN_DEP"] + abort_if_use_local_rndeps_with_no_file() + end - artifacts_exists = ENV["RCT_USE_RN_DEP"] == "1" && (@@use_nightly ? nightly_artifact_exists(@@react_native_version) : release_artifact_exists(@@react_native_version)) - use_local_xcframework = ENV["RCT_USE_LOCAL_RN_DEP"] && File.exist?(ENV["RCT_USE_LOCAL_RN_DEP"]) + artifacts_exists = ENV["RCT_USE_RN_DEP"] == "1" && (@@use_nightly ? nightly_artifact_exists(@@react_native_version) : release_artifact_exists(@@react_native_version)) + use_local_xcframework = ENV["RCT_USE_LOCAL_RN_DEP"] && File.exist?(ENV["RCT_USE_LOCAL_RN_DEP"]) - if ENV["RCT_USE_LOCAL_RN_DEP"] - if !File.exist?(ENV["RCT_USE_LOCAL_RN_DEP"]) - abort("RCT_USE_LOCAL_RN_DEP is set to #{ENV["RCT_USE_LOCAL_RN_DEP"]} but the file does not exist!") + @@build_from_source = !use_local_xcframework && !artifacts_exists + + if @@build_from_source && ENV["RCT_USE_LOCAL_RN_DEP"] && !use_local_xcframework + rndeps_log("No local xcframework found, reverting to building from source.") + end + if @@build_from_source && ENV["RCT_USE_PREBUILT_RNCORE"] && !artifacts_exists + rndeps_log("No prebuilt artifacts found, reverting to building from source.") end + rndeps_log("Building from source: #{@@build_from_source}") + rndeps_log("Source: #{self.resolve_podspec_source()}") end + end - @@build_from_source = !use_local_xcframework && !artifacts_exists - - rndeps_log("Building from source: #{@@build_from_source}") + def self.abort_if_use_local_rndeps_with_no_file() + if !File.exist?(ENV["RCT_USE_LOCAL_RN_DEP"]) + abort("RCT_USE_LOCAL_RN_DEP is set to #{ENV["RCT_USE_LOCAL_RN_DEP"]} but the file does not exist!") + end end def self.podspec_source_download_prebuild_release_tarball() @@ -205,7 +237,7 @@ def self.artifact_exists(tarball_url) return (`curl -o /dev/null --silent -Iw '%{http_code}' -L "#{tarball_url}"` == "200") end - def self.rndeps_log(message, level = :warning) + def self.rndeps_log(message, level = :info) if !Object.const_defined?("Pod::UI") return end @@ -220,7 +252,16 @@ def self.rndeps_log(message, level = :warning) end end - def self.resolve_url_redirects(url) - return (`curl -Ls -o /dev/null -w %{url_effective} \"#{url}\"`) + def self.get_nightly_npm_version() + uri = URI('https://registry.npmjs.org/react-native/nightly') + response = Net::HTTP.get_response(uri) + + unless response.is_a?(Net::HTTPSuccess) + raise "Couldn't get an answer from NPM: #{response.code} #{response.message}" + end + + json = JSON.parse(response.body) + latest_nightly = json['version'] + return latest_nightly end end diff --git a/packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap b/packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap index 48482e5b4049c3..097e16d4a9e042 100644 --- a/packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap +++ b/packages/react-native/scripts/codegen/__tests__/__snapshots__/generate-artifacts-executor-test.js.snap @@ -412,30 +412,53 @@ use_frameworks = ENV['USE_FRAMEWORKS'] != nil folly_compiler_flags = Helpers::Constants.folly_config[:compiler_flags] boost_compiler_flags = Helpers::Constants.boost_config[:compiler_flags] -header_search_paths = [ - \\"\\\\\\"$(PODS_ROOT)/ReactNativeDependencies\\\\\\"\\", - \\"\\\\\\"\${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\\\\\\"\\", - \\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-Fabric\\\\\\"\\", - \\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\\\\\\"\\", - \\"\\\\\\"$(PODS_ROOT)/Headers/Private/Yoga\\\\\\"\\", - \\"\\\\\\"$(PODS_TARGET_SRCROOT)\\\\\\"\\", -] +header_search_paths = [] framework_search_paths = [] -if use_frameworks - ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-Fabric\\", \\"React_Fabric\\", [\\"react/renderer/components/view/platform/cxx\\"]) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-FabricImage\\", \\"React_FabricImage\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-graphics\\", \\"React_graphics\\", [\\"react/renderer/graphics/platform/ios\\"])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"ReactCommon\\", \\"ReactCommon\\", [\\"react/nativemodule/core\\"])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-NativeModulesApple\\", \\"React_NativeModulesApple\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-RCTFabric\\", \\"RCTFabric\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-debug\\", \\"React_debug\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-rendererdebug\\", \\"React_rendererdebug\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-utils\\", \\"React_utils\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-featureflags\\", \\"React_featureflags\\", [])) - .each { |search_path| - header_search_paths << \\"\\\\\\"#{search_path}\\\\\\"\\" - } +if ReactNativeCoreUtils.build_rncore_from_source() + + header_search_paths = [ + \\"\\\\\\"$(PODS_ROOT)/ReactNativeDependencies\\\\\\"\\", + \\"\\\\\\"\${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\\\\\\"\\", + \\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-Fabric\\\\\\"\\", + \\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\\\\\\"\\", + \\"\\\\\\"$(PODS_ROOT)/Headers/Private/Yoga\\\\\\"\\", + \\"\\\\\\"$(PODS_TARGET_SRCROOT)\\\\\\"\\", + ] + + if use_frameworks + ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-Fabric\\", \\"React_Fabric\\", [\\"react/renderer/components/view/platform/cxx\\"]) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-FabricImage\\", \\"React_FabricImage\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-graphics\\", \\"React_graphics\\", [\\"react/renderer/graphics/platform/ios\\"])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"ReactCommon\\", \\"ReactCommon\\", [\\"react/nativemodule/core\\"])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-NativeModulesApple\\", \\"React_NativeModulesApple\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-RCTFabric\\", \\"RCTFabric\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-debug\\", \\"React_debug\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-rendererdebug\\", \\"React_rendererdebug\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-utils\\", \\"React_utils\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-featureflags\\", \\"React_featureflags\\", [])) + .each { |search_path| + header_search_paths << \\"\\\\\\"#{search_path}\\\\\\"\\" + } + end +else + header_search_paths = [ + \\"$(PODS_ROOT)/Headers/Public/React-Core-prebuilt/ReactCommon\\", + \\"$(PODS_ROOT)/ReactNativeDependencies\\", + \\"$(REACT_NATIVE_PATH)/Libraries\\", + \\"$(REACT_NATIVE_PATH)/Libraries/FBLazyVector\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/Libraries\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/Libraries/AppDelegate\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/RCTDeprecation\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/ReactCommon\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/ReactCommon/jsi\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/ReactCommon/yoga\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/react/nativemodule/core\\", + \\"\${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\\", + \\"\${REACT_NATIVE_PATH}/ReactCommon/jsi\\", + \\"\${REACT_NATIVE_PATH}/ReactCommon/yoga\\", + ] end Pod::Spec.new do |s| @@ -457,25 +480,32 @@ Pod::Spec.new do |s| \\"OTHER_CPLUSPLUSFLAGS\\" => \\"$(inherited) #{folly_compiler_flags} #{boost_compiler_flags}\\" } - s.dependency \\"React-jsiexecutor\\" - s.dependency \\"RCTRequired\\" - s.dependency \\"RCTTypeSafety\\" - s.dependency \\"React-Core\\" - s.dependency \\"React-jsi\\" - s.dependency \\"ReactCommon/turbomodule/bridging\\" - s.dependency \\"ReactCommon/turbomodule/core\\" - s.dependency \\"React-NativeModulesApple\\" - s.dependency 'React-graphics' - s.dependency 'React-rendererdebug' - s.dependency 'React-Fabric' - s.dependency 'React-FabricImage' - s.dependency 'React-debug' - s.dependency 'React-utils' - s.dependency 'React-featureflags' - s.dependency 'React-RCTAppDelegate' - - depend_on_js_engine(s) - add_rn_third_party_dependencies(s) + if ReactNativeCoreUtils.build_rncore_from_source() + + s.dependency \\"React-jsiexecutor\\" + s.dependency \\"RCTRequired\\" + s.dependency \\"RCTTypeSafety\\" + s.dependency \\"React-Core\\" + s.dependency \\"React-jsi\\" + s.dependency \\"ReactCommon/turbomodule/bridging\\" + s.dependency \\"ReactCommon/turbomodule/core\\" + s.dependency \\"React-NativeModulesApple\\" + s.dependency 'React-graphics' + s.dependency 'React-rendererdebug' + s.dependency 'React-Fabric' + s.dependency 'React-FabricImage' + s.dependency 'React-debug' + s.dependency 'React-utils' + s.dependency 'React-featureflags' + s.dependency 'React-RCTAppDelegate' + + depend_on_js_engine(s) + add_rn_third_party_dependencies(s) + + else + s.dependency 'React-Core-prebuilt' + s.dependency 'ReactNativeDependencies' + end s.script_phases = { 'name' => 'Generate Specs', @@ -887,30 +917,53 @@ use_frameworks = ENV['USE_FRAMEWORKS'] != nil folly_compiler_flags = Helpers::Constants.folly_config[:compiler_flags] boost_compiler_flags = Helpers::Constants.boost_config[:compiler_flags] -header_search_paths = [ - \\"\\\\\\"$(PODS_ROOT)/ReactNativeDependencies\\\\\\"\\", - \\"\\\\\\"\${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\\\\\\"\\", - \\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-Fabric\\\\\\"\\", - \\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\\\\\\"\\", - \\"\\\\\\"$(PODS_ROOT)/Headers/Private/Yoga\\\\\\"\\", - \\"\\\\\\"$(PODS_TARGET_SRCROOT)\\\\\\"\\", -] +header_search_paths = [] framework_search_paths = [] -if use_frameworks - ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-Fabric\\", \\"React_Fabric\\", [\\"react/renderer/components/view/platform/cxx\\"]) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-FabricImage\\", \\"React_FabricImage\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-graphics\\", \\"React_graphics\\", [\\"react/renderer/graphics/platform/ios\\"])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"ReactCommon\\", \\"ReactCommon\\", [\\"react/nativemodule/core\\"])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-NativeModulesApple\\", \\"React_NativeModulesApple\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-RCTFabric\\", \\"RCTFabric\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-debug\\", \\"React_debug\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-rendererdebug\\", \\"React_rendererdebug\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-utils\\", \\"React_utils\\", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-featureflags\\", \\"React_featureflags\\", [])) - .each { |search_path| - header_search_paths << \\"\\\\\\"#{search_path}\\\\\\"\\" - } +if ReactNativeCoreUtils.build_rncore_from_source() + + header_search_paths = [ + \\"\\\\\\"$(PODS_ROOT)/ReactNativeDependencies\\\\\\"\\", + \\"\\\\\\"\${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\\\\\\"\\", + \\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-Fabric\\\\\\"\\", + \\"\\\\\\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\\\\\\"\\", + \\"\\\\\\"$(PODS_ROOT)/Headers/Private/Yoga\\\\\\"\\", + \\"\\\\\\"$(PODS_TARGET_SRCROOT)\\\\\\"\\", + ] + + if use_frameworks + ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-Fabric\\", \\"React_Fabric\\", [\\"react/renderer/components/view/platform/cxx\\"]) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-FabricImage\\", \\"React_FabricImage\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-graphics\\", \\"React_graphics\\", [\\"react/renderer/graphics/platform/ios\\"])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"ReactCommon\\", \\"ReactCommon\\", [\\"react/nativemodule/core\\"])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-NativeModulesApple\\", \\"React_NativeModulesApple\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-RCTFabric\\", \\"RCTFabric\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-debug\\", \\"React_debug\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-rendererdebug\\", \\"React_rendererdebug\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-utils\\", \\"React_utils\\", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks(\\"PODS_CONFIGURATION_BUILD_DIR\\", \\"React-featureflags\\", \\"React_featureflags\\", [])) + .each { |search_path| + header_search_paths << \\"\\\\\\"#{search_path}\\\\\\"\\" + } + end +else + header_search_paths = [ + \\"$(PODS_ROOT)/Headers/Public/React-Core-prebuilt/ReactCommon\\", + \\"$(PODS_ROOT)/ReactNativeDependencies\\", + \\"$(REACT_NATIVE_PATH)/Libraries\\", + \\"$(REACT_NATIVE_PATH)/Libraries/FBLazyVector\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/Libraries\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/Libraries/AppDelegate\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/RCTDeprecation\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/ReactCommon\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/ReactCommon/jsi\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/ReactCommon/yoga\\", + \\"\${PODS_ROOT}/Headers/Public/React-Core-prebuilt/react/nativemodule/core\\", + \\"\${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\\", + \\"\${REACT_NATIVE_PATH}/ReactCommon/jsi\\", + \\"\${REACT_NATIVE_PATH}/ReactCommon/yoga\\", + ] end Pod::Spec.new do |s| @@ -932,25 +985,32 @@ Pod::Spec.new do |s| \\"OTHER_CPLUSPLUSFLAGS\\" => \\"$(inherited) #{folly_compiler_flags} #{boost_compiler_flags}\\" } - s.dependency \\"React-jsiexecutor\\" - s.dependency \\"RCTRequired\\" - s.dependency \\"RCTTypeSafety\\" - s.dependency \\"React-Core\\" - s.dependency \\"React-jsi\\" - s.dependency \\"ReactCommon/turbomodule/bridging\\" - s.dependency \\"ReactCommon/turbomodule/core\\" - s.dependency \\"React-NativeModulesApple\\" - s.dependency 'React-graphics' - s.dependency 'React-rendererdebug' - s.dependency 'React-Fabric' - s.dependency 'React-FabricImage' - s.dependency 'React-debug' - s.dependency 'React-utils' - s.dependency 'React-featureflags' - s.dependency 'React-RCTAppDelegate' - - depend_on_js_engine(s) - add_rn_third_party_dependencies(s) + if ReactNativeCoreUtils.build_rncore_from_source() + + s.dependency \\"React-jsiexecutor\\" + s.dependency \\"RCTRequired\\" + s.dependency \\"RCTTypeSafety\\" + s.dependency \\"React-Core\\" + s.dependency \\"React-jsi\\" + s.dependency \\"ReactCommon/turbomodule/bridging\\" + s.dependency \\"ReactCommon/turbomodule/core\\" + s.dependency \\"React-NativeModulesApple\\" + s.dependency 'React-graphics' + s.dependency 'React-rendererdebug' + s.dependency 'React-Fabric' + s.dependency 'React-FabricImage' + s.dependency 'React-debug' + s.dependency 'React-utils' + s.dependency 'React-featureflags' + s.dependency 'React-RCTAppDelegate' + + depend_on_js_engine(s) + add_rn_third_party_dependencies(s) + + else + s.dependency 'React-Core-prebuilt' + s.dependency 'ReactNativeDependencies' + end s.script_phases = { 'name' => 'Generate Specs', diff --git a/packages/react-native/scripts/codegen/templates/ReactCodegen.podspec.template b/packages/react-native/scripts/codegen/templates/ReactCodegen.podspec.template index e92927a20ee960..a6bcc7f17b791a 100644 --- a/packages/react-native/scripts/codegen/templates/ReactCodegen.podspec.template +++ b/packages/react-native/scripts/codegen/templates/ReactCodegen.podspec.template @@ -16,30 +16,53 @@ use_frameworks = ENV['USE_FRAMEWORKS'] != nil folly_compiler_flags = Helpers::Constants.folly_config[:compiler_flags] boost_compiler_flags = Helpers::Constants.boost_config[:compiler_flags] -header_search_paths = [ - "\"$(PODS_ROOT)/ReactNativeDependencies\"", - "\"${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\"", - "\"$(PODS_ROOT)/Headers/Private/React-Fabric\"", - "\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\"", - "\"$(PODS_ROOT)/Headers/Private/Yoga\"", - "\"$(PODS_TARGET_SRCROOT)\"", -] +header_search_paths = [] framework_search_paths = [] -if use_frameworks - ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-Fabric", "React_Fabric", ["react/renderer/components/view/platform/cxx"]) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-FabricImage", "React_FabricImage", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-graphics", "React_graphics", ["react/renderer/graphics/platform/ios"])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "ReactCommon", "ReactCommon", ["react/nativemodule/core"])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-NativeModulesApple", "React_NativeModulesApple", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-RCTFabric", "RCTFabric", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-debug", "React_debug", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-rendererdebug", "React_rendererdebug", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-utils", "React_utils", [])) - .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-featureflags", "React_featureflags", [])) - .each { |search_path| - header_search_paths << "\"#{search_path}\"" - } +if ReactNativeCoreUtils.build_rncore_from_source() + + header_search_paths = [ + "\"$(PODS_ROOT)/ReactNativeDependencies\"", + "\"${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\"", + "\"$(PODS_ROOT)/Headers/Private/React-Fabric\"", + "\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\"", + "\"$(PODS_ROOT)/Headers/Private/Yoga\"", + "\"$(PODS_TARGET_SRCROOT)\"", + ] + + if use_frameworks + ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-Fabric", "React_Fabric", ["react/renderer/components/view/platform/cxx"]) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-FabricImage", "React_FabricImage", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-graphics", "React_graphics", ["react/renderer/graphics/platform/ios"])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "ReactCommon", "ReactCommon", ["react/nativemodule/core"])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-NativeModulesApple", "React_NativeModulesApple", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-RCTFabric", "RCTFabric", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-debug", "React_debug", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-rendererdebug", "React_rendererdebug", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-utils", "React_utils", [])) + .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-featureflags", "React_featureflags", [])) + .each { |search_path| + header_search_paths << "\"#{search_path}\"" + } + end +else + header_search_paths = [ + "$(PODS_ROOT)/Headers/Public/React-Core-prebuilt/ReactCommon", + "$(PODS_ROOT)/ReactNativeDependencies", + "$(REACT_NATIVE_PATH)/Libraries", + "$(REACT_NATIVE_PATH)/Libraries/FBLazyVector", + "${PODS_ROOT}/Headers/Public/React-Core-prebuilt", + "${PODS_ROOT}/Headers/Public/React-Core-prebuilt/Libraries", + "${PODS_ROOT}/Headers/Public/React-Core-prebuilt/Libraries/AppDelegate", + "${PODS_ROOT}/Headers/Public/React-Core-prebuilt/RCTDeprecation", + "${PODS_ROOT}/Headers/Public/React-Core-prebuilt/ReactCommon", + "${PODS_ROOT}/Headers/Public/React-Core-prebuilt/ReactCommon/jsi", + "${PODS_ROOT}/Headers/Public/React-Core-prebuilt/ReactCommon/yoga", + "${PODS_ROOT}/Headers/Public/React-Core-prebuilt/react/nativemodule/core", + "${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components", + "${REACT_NATIVE_PATH}/ReactCommon/jsi", + "${REACT_NATIVE_PATH}/ReactCommon/yoga", + ] end Pod::Spec.new do |s| @@ -61,25 +84,32 @@ Pod::Spec.new do |s| "OTHER_CPLUSPLUSFLAGS" => "$(inherited) #{folly_compiler_flags} #{boost_compiler_flags}" } - s.dependency "React-jsiexecutor" - s.dependency "RCTRequired" - s.dependency "RCTTypeSafety" - s.dependency "React-Core" - s.dependency "React-jsi" - s.dependency "ReactCommon/turbomodule/bridging" - s.dependency "ReactCommon/turbomodule/core" - s.dependency "React-NativeModulesApple" - s.dependency 'React-graphics' - s.dependency 'React-rendererdebug' - s.dependency 'React-Fabric' - s.dependency 'React-FabricImage' - s.dependency 'React-debug' - s.dependency 'React-utils' - s.dependency 'React-featureflags' - s.dependency 'React-RCTAppDelegate' + if ReactNativeCoreUtils.build_rncore_from_source() + + s.dependency "React-jsiexecutor" + s.dependency "RCTRequired" + s.dependency "RCTTypeSafety" + s.dependency "React-Core" + s.dependency "React-jsi" + s.dependency "ReactCommon/turbomodule/bridging" + s.dependency "ReactCommon/turbomodule/core" + s.dependency "React-NativeModulesApple" + s.dependency 'React-graphics' + s.dependency 'React-rendererdebug' + s.dependency 'React-Fabric' + s.dependency 'React-FabricImage' + s.dependency 'React-debug' + s.dependency 'React-utils' + s.dependency 'React-featureflags' + s.dependency 'React-RCTAppDelegate' + + depend_on_js_engine(s) + add_rn_third_party_dependencies(s) - depend_on_js_engine(s) - add_rn_third_party_dependencies(s) + else + s.dependency 'React-Core-prebuilt' + s.dependency 'ReactNativeDependencies' + end s.script_phases = { 'name' => 'Generate Specs', diff --git a/packages/react-native/scripts/ios-prebuild/xcframework.js b/packages/react-native/scripts/ios-prebuild/xcframework.js index ffecf7a74e2270..af341175546b4c 100644 --- a/packages/react-native/scripts/ios-prebuild/xcframework.js +++ b/packages/react-native/scripts/ios-prebuild/xcframework.js @@ -69,6 +69,8 @@ const HEADERFILE_IGNORE_LIST = [ 'JsArgumentHelpers-inl.h', 'RCTJscInstance.h', 'RCTJSThreadManager.h', + 'YGEnums.h', + 'YGNode.h', ]; function buildXCFrameworks( @@ -106,8 +108,9 @@ function buildXCFrameworks( } catch (error) { frameworkLog( `Error building XCFramework: ${error.message}. Check if the build was successful.`, - 'warning', + 'error', ); + return; } // Copy header files from the headers folder that we used to build the swift package @@ -124,7 +127,22 @@ function buildXCFrameworks( ); // Create the module map file - createModuleMapFile(outputPath, umbrellaHeaderFile); + const moduleMapFile = createModuleMapFile(outputPath, umbrellaHeaderFile); + if (!moduleMapFile) { + frameworkLog( + 'Failed to create module map file. The XCFramework may not work correctly. Stopping.', + 'error', + ); + return; + } + + // Get the platforms in the framework folder and copy modulemaps and headers into each platform folder + linkArchFolders( + outputPath, + moduleMapFile, + umbrellaHeaderFile, + outputHeaderFiles, + ); // Copy Symbols to symbols folder const symbolPaths = frameworkFolders.map(framework => @@ -144,6 +162,91 @@ function buildXCFrameworks( } } +function linkArchFolders( + outputPath /*:string*/, + moduleMapFile /*:string*/, + umbrellaHeaderFile /*:string*/, + outputHeaderFiles /*: Array */, +) { + frameworkLog('Linking modules and headers to platform folders...'); + const headerRootFolder = path.dirname(umbrellaHeaderFile); + + fs.readdirSync(outputPath) + .filter(folder => { + const folderPath = path.join(outputPath, folder); + return ( + fs.statSync(folderPath).isDirectory() && + folder !== 'Headers' && + folder !== 'Modules' + ); + }) + .forEach(folder => { + // Get full platform folder path + const platformFolder = path.join(outputPath, folder); + // Link the Modules folder into the platform folder + const targetModulesFolder = path.join( + platformFolder, + 'React.Framework', + 'Modules', + ); + createFolderIfNotExists(targetModulesFolder); + try { + fs.linkSync( + moduleMapFile, + path.join(targetModulesFolder, path.basename(moduleMapFile)), + ); + } catch (error) { + frameworkLog( + `Error copying module map file: ${error.message}. Check if the file exists at ${moduleMapFile}.`, + 'error', + ); + } + // Copy headers folder into the platform folder + const targetHeadersFolder = path.join( + platformFolder, + 'React.Framework', + 'Headers', + ); + // Link header files into the platform folder + outputHeaderFiles.forEach(headerFile => { + // Get the relative path of the header file based on the root folder + const relativePath = path.relative(headerRootFolder, headerFile); + // Create the target folder for the header file + const targetFolder = path.join( + targetHeadersFolder, + path.dirname(relativePath), + ); + // Create the target folder if it doesn't exist + createFolderIfNotExists(targetFolder); + // Link the header file to the target folder + try { + fs.linkSync( + headerFile, + path.join(targetFolder, path.basename(headerFile)), + ); + } catch (error) { + frameworkLog( + `Error linking header file: ${error.message}. Check if the file exists.`, + 'error', + ); + } + }); + // Link the umbrella header file to the target headers folder + try { + const targetUmbrellaPath = path.join( + targetHeadersFolder, + 'React-umbrella.h', + ); + fs.linkSync(umbrellaHeaderFile, targetUmbrellaPath); + } catch (error) { + frameworkLog( + `Error linking umbrella header file: ${error.message}. Check if the file exists.`, + 'error', + ); + } + }); +} + function copyHeaderFiles( headersSourceFolder /*: string */, outputPath /*: string */, @@ -249,7 +352,11 @@ function createUmbrellaHeaderFile( return umbrellaHeaderFile; } -const cppHeaderRegex = /(#include|#import)\s*<[^.>]+>|\bnamespace\s+[\w:]+::/; +// This regex matches some C++ construct that might be present in a header file. +// To uniquely identify them. We need to exclude headers with C++ constructs from the module map +// otherwise Swift won't be able to import the React.xcframework +const cppHeaderRegex = + /(#include|#import)\s*<[^.>]+>|\bnamespace\s+[\w:]+::|NS_ENUM\s*\([^)]*\)|NS_OPTIONS\s*\([^)]*\)|typedef\s+enum|static\s+const|@interface|static\s+inline/; function isCppHeaderFile(headerFilePath /*: string */) /*: boolean */ { // Check if there is a cpp or mm file with the same name @@ -299,21 +406,24 @@ function createModuleMapFile( // Create the module map file const moduleMapFile = path.join(moduleMapFolder, 'module.modulemap'); frameworkLog('Creating module map file: ' + moduleMapFile); - const moduleMapContent = `module React { - umbrella header "../Headers/${path.basename(umbrellaPath)}" + const moduleMapContent = `framework module React { + umbrella header "${path.basename(umbrellaPath)}" export * module * { export * } }`; try { fs.writeFileSync(moduleMapFile, moduleMapContent); + return moduleMapFile; } catch (error) { frameworkLog( `Error creating module map file: ${error.message}. Check if the file exists.`, 'warning', ); + return null; } } + function cleanPlatformFolders(outputPath /*:string*/) { if (!fs.existsSync(outputPath)) { return; diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb index 4c6604af32f10e..79050763b75dc5 100644 --- a/packages/react-native/scripts/react_native_pods.rb +++ b/packages/react-native/scripts/react_native_pods.rb @@ -9,6 +9,7 @@ require_relative './react_native_pods_utils/script_phases.rb' require_relative './cocoapods/jsengine.rb' require_relative './cocoapods/rndependencies.rb' +require_relative './cocoapods/rncore.rb' require_relative './cocoapods/fabric.rb' require_relative './cocoapods/codegen.rb' require_relative './cocoapods/codegen_utils.rb' @@ -19,6 +20,7 @@ require_relative './cocoapods/helpers.rb' require_relative './cocoapods/privacy_manifest_utils.rb' require_relative './cocoapods/spm.rb' +require_relative './cocoapods/rncore.rb' # Importing to expose use_native_modules! require_relative './cocoapods/autolinking.rb' @@ -105,80 +107,96 @@ def use_react_native! ( # Update ReactNativeDependencies so that we can easily switch between source and prebuilt ReactNativeDependenciesUtils.setup_react_native_dependencies(prefix, react_native_version) + # Update ReactNativeCoreUtils so that we can easily switch between source and prebuilt + ReactNativeCoreUtils.setup_rncore(prefix, react_native_version) + Pod::UI.puts "Configuring the target with the #{new_arch_enabled ? "New" : "Legacy"} Architecture\n" - # The Pods which should be included in all projects - pod 'FBLazyVector', :path => "#{prefix}/Libraries/FBLazyVector" - pod 'RCTRequired', :path => "#{prefix}/Libraries/Required" - pod 'RCTTypeSafety', :path => "#{prefix}/Libraries/TypeSafety", :modular_headers => true - pod 'React', :path => "#{prefix}/" - pod 'React-Core', :path => "#{prefix}/" - pod 'React-CoreModules', :path => "#{prefix}/React/CoreModules" - pod 'React-RCTRuntime', :path => "#{prefix}/React/Runtime" - pod 'React-RCTAppDelegate', :path => "#{prefix}/Libraries/AppDelegate" - pod 'React-RCTActionSheet', :path => "#{prefix}/Libraries/ActionSheetIOS" - pod 'React-RCTAnimation', :path => "#{prefix}/Libraries/NativeAnimation" - pod 'React-RCTBlob', :path => "#{prefix}/Libraries/Blob" - pod 'React-RCTImage', :path => "#{prefix}/Libraries/Image" - pod 'React-RCTLinking', :path => "#{prefix}/Libraries/LinkingIOS" - pod 'React-RCTNetwork', :path => "#{prefix}/Libraries/Network" - pod 'React-RCTSettings', :path => "#{prefix}/Libraries/Settings" - pod 'React-RCTText', :path => "#{prefix}/Libraries/Text" - pod 'React-RCTVibration', :path => "#{prefix}/Libraries/Vibration" - pod 'React-Core/RCTWebSocket', :path => "#{prefix}/" - pod 'React-cxxreact', :path => "#{prefix}/ReactCommon/cxxreact" - pod 'React-debug', :path => "#{prefix}/ReactCommon/react/debug" - pod 'React-utils', :path => "#{prefix}/ReactCommon/react/utils" - pod 'React-featureflags', :path => "#{prefix}/ReactCommon/react/featureflags" - pod 'React-featureflagsnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/featureflags" - pod 'React-microtasksnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/microtasks" - pod 'React-idlecallbacksnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/idlecallbacks" - pod 'React-domnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/dom" - pod 'React-defaultsnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/defaults" - pod 'React-Mapbuffer', :path => "#{prefix}/ReactCommon" - pod 'React-jserrorhandler', :path => "#{prefix}/ReactCommon/jserrorhandler" - pod 'RCTDeprecation', :path => "#{prefix}/ReactApple/Libraries/RCTFoundation/RCTDeprecation" - pod 'React-RCTFBReactNativeSpec', :path => "#{prefix}/React" - pod 'React-jsi', :path => "#{prefix}/ReactCommon/jsi" - - if hermes_enabled - setup_hermes!(:react_native_path => prefix) - end + if ReactNativeCoreUtils.build_rncore_from_source() + # The Pods which should be included in all projects + pod 'FBLazyVector', :path => "#{prefix}/Libraries/FBLazyVector" + pod 'RCTRequired', :path => "#{prefix}/Libraries/Required" + pod 'RCTTypeSafety', :path => "#{prefix}/Libraries/TypeSafety", :modular_headers => true + pod 'React', :path => "#{prefix}/" + pod 'React-Core', :path => "#{prefix}/" + pod 'React-CoreModules', :path => "#{prefix}/React/CoreModules" + pod 'React-RCTRuntime', :path => "#{prefix}/React/Runtime" + pod 'React-RCTAppDelegate', :path => "#{prefix}/Libraries/AppDelegate" + pod 'React-RCTActionSheet', :path => "#{prefix}/Libraries/ActionSheetIOS" + pod 'React-RCTAnimation', :path => "#{prefix}/Libraries/NativeAnimation" + pod 'React-RCTBlob', :path => "#{prefix}/Libraries/Blob" + pod 'React-RCTImage', :path => "#{prefix}/Libraries/Image" + pod 'React-RCTLinking', :path => "#{prefix}/Libraries/LinkingIOS" + pod 'React-RCTNetwork', :path => "#{prefix}/Libraries/Network" + pod 'React-RCTSettings', :path => "#{prefix}/Libraries/Settings" + pod 'React-RCTText', :path => "#{prefix}/Libraries/Text" + pod 'React-RCTVibration', :path => "#{prefix}/Libraries/Vibration" + pod 'React-Core/RCTWebSocket', :path => "#{prefix}/" + pod 'React-cxxreact', :path => "#{prefix}/ReactCommon/cxxreact" + pod 'React-debug', :path => "#{prefix}/ReactCommon/react/debug" + pod 'React-utils', :path => "#{prefix}/ReactCommon/react/utils" + pod 'React-featureflags', :path => "#{prefix}/ReactCommon/react/featureflags" + pod 'React-featureflagsnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/featureflags" + pod 'React-microtasksnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/microtasks" + pod 'React-idlecallbacksnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/idlecallbacks" + pod 'React-domnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/dom" + pod 'React-defaultsnativemodule', :path => "#{prefix}/ReactCommon/react/nativemodule/defaults" + pod 'React-Mapbuffer', :path => "#{prefix}/ReactCommon" + pod 'React-jserrorhandler', :path => "#{prefix}/ReactCommon/jserrorhandler" + pod 'RCTDeprecation', :path => "#{prefix}/ReactApple/Libraries/RCTFoundation/RCTDeprecation" + pod 'React-RCTFBReactNativeSpec', :path => "#{prefix}/React" + pod 'React-jsi', :path => "#{prefix}/ReactCommon/jsi" + + if hermes_enabled + setup_hermes!(:react_native_path => prefix) + end - pod 'React-jsiexecutor', :path => "#{prefix}/ReactCommon/jsiexecutor" - pod 'React-jsinspector', :path => "#{prefix}/ReactCommon/jsinspector-modern" - pod 'React-jsitooling', :path => "#{prefix}/ReactCommon/jsitooling" - pod 'React-jsinspectorcdp', :path => "#{prefix}/ReactCommon/jsinspector-modern/cdp" - pod 'React-jsinspectornetwork', :path => "#{prefix}/ReactCommon/jsinspector-modern/network" - pod 'React-jsinspectortracing', :path => "#{prefix}/ReactCommon/jsinspector-modern/tracing" - - pod 'React-callinvoker', :path => "#{prefix}/ReactCommon/callinvoker" - pod 'React-performancetimeline', :path => "#{prefix}/ReactCommon/react/performance/timeline" - pod 'React-timing', :path => "#{prefix}/ReactCommon/react/timing" - pod 'React-runtimeexecutor', :path => "#{prefix}/ReactCommon/runtimeexecutor" - pod 'React-runtimescheduler', :path => "#{prefix}/ReactCommon/react/renderer/runtimescheduler" - pod 'React-renderercss', :path => "#{prefix}/ReactCommon/react/renderer/css" - pod 'React-rendererdebug', :path => "#{prefix}/ReactCommon/react/renderer/debug" - pod 'React-rendererconsistency', :path => "#{prefix}/ReactCommon/react/renderer/consistency" - pod 'React-perflogger', :path => "#{prefix}/ReactCommon/reactperflogger" - pod 'React-oscompat', :path => "#{prefix}/ReactCommon/oscompat" - pod 'React-logger', :path => "#{prefix}/ReactCommon/logger" - pod 'ReactCommon/turbomodule/core', :path => "#{prefix}/ReactCommon", :modular_headers => true - pod 'React-NativeModulesApple', :path => "#{prefix}/ReactCommon/react/nativemodule/core/platform/ios", :modular_headers => true - pod 'Yoga', :path => "#{prefix}/ReactCommon/yoga", :modular_headers => true - - if ReactNativeDependenciesUtils.build_react_native_deps_from_source() - pod 'DoubleConversion', :podspec => "#{prefix}/third-party-podspecs/DoubleConversion.podspec" - pod 'glog', :podspec => "#{prefix}/third-party-podspecs/glog.podspec" - pod 'boost', :podspec => "#{prefix}/third-party-podspecs/boost.podspec" - pod 'fast_float', :podspec => "#{prefix}/third-party-podspecs/fast_float.podspec" - pod 'fmt', :podspec => "#{prefix}/third-party-podspecs/fmt.podspec", :modular_headers => true - pod 'RCT-Folly', :podspec => "#{prefix}/third-party-podspecs/RCT-Folly.podspec", :modular_headers => true - pod 'SocketRocket', "~> #{Helpers::Constants::socket_rocket_config[:version]}", :modular_headers => true + pod 'React-jsiexecutor', :path => "#{prefix}/ReactCommon/jsiexecutor" + pod 'React-jsinspector', :path => "#{prefix}/ReactCommon/jsinspector-modern" + pod 'React-jsitooling', :path => "#{prefix}/ReactCommon/jsitooling" + pod 'React-jsinspectorcdp', :path => "#{prefix}/ReactCommon/jsinspector-modern/cdp" + pod 'React-jsinspectornetwork', :path => "#{prefix}/ReactCommon/jsinspector-modern/network" + pod 'React-jsinspectortracing', :path => "#{prefix}/ReactCommon/jsinspector-modern/tracing" + + pod 'React-callinvoker', :path => "#{prefix}/ReactCommon/callinvoker" + pod 'React-performancetimeline', :path => "#{prefix}/ReactCommon/react/performance/timeline" + pod 'React-timing', :path => "#{prefix}/ReactCommon/react/timing" + pod 'React-runtimeexecutor', :path => "#{prefix}/ReactCommon/runtimeexecutor" + pod 'React-runtimescheduler', :path => "#{prefix}/ReactCommon/react/renderer/runtimescheduler" + pod 'React-renderercss', :path => "#{prefix}/ReactCommon/react/renderer/css" + pod 'React-rendererdebug', :path => "#{prefix}/ReactCommon/react/renderer/debug" + pod 'React-rendererconsistency', :path => "#{prefix}/ReactCommon/react/renderer/consistency" + pod 'React-perflogger', :path => "#{prefix}/ReactCommon/reactperflogger" + pod 'React-oscompat', :path => "#{prefix}/ReactCommon/oscompat" + pod 'React-logger', :path => "#{prefix}/ReactCommon/logger" + pod 'ReactCommon/turbomodule/core', :path => "#{prefix}/ReactCommon", :modular_headers => true + pod 'React-NativeModulesApple', :path => "#{prefix}/ReactCommon/react/nativemodule/core/platform/ios", :modular_headers => true + pod 'Yoga', :path => "#{prefix}/ReactCommon/yoga", :modular_headers => true + setup_fabric!(:react_native_path => prefix) + setup_bridgeless!(:react_native_path => prefix, :use_hermes => hermes_enabled) + + if ReactNativeDependenciesUtils.build_react_native_deps_from_source() + pod 'DoubleConversion', :podspec => "#{prefix}/third-party-podspecs/DoubleConversion.podspec" + pod 'glog', :podspec => "#{prefix}/third-party-podspecs/glog.podspec" + pod 'boost', :podspec => "#{prefix}/third-party-podspecs/boost.podspec" + pod 'fast_float', :podspec => "#{prefix}/third-party-podspecs/fast_float.podspec" + pod 'fmt', :podspec => "#{prefix}/third-party-podspecs/fmt.podspec", :modular_headers => true + pod 'RCT-Folly', :podspec => "#{prefix}/third-party-podspecs/RCT-Folly.podspec", :modular_headers => true + pod 'SocketRocket', "~> #{Helpers::Constants::socket_rocket_config[:version]}", :modular_headers => true + else + pod 'ReactNativeDependencies', :podspec => "#{prefix}/third-party-podspecs/ReactNativeDependencies.podspec", :modular_headers => true + end else + # Install prebuilt React Native Core and React Native Dependencies + ReactNativeCoreUtils.rncore_log("Using React Native Core and React Native Dependencies prebuilt versions.") + pod 'React-Core-prebuilt', :podspec => "#{prefix}/React-Core-prebuilt.podspec", :modular_headers => true pod 'ReactNativeDependencies', :podspec => "#{prefix}/third-party-podspecs/ReactNativeDependencies.podspec", :modular_headers => true + pod 'hermes-engine', :podspec => "#{prefix}/sdks/hermes-engine/hermes-engine.podspec" end + pod 'ReactCodegen', :path => $CODEGEN_OUTPUT_DIR, :modular_headers => true + pod 'ReactAppDependencyProvider', :path => $CODEGEN_OUTPUT_DIR, :modular_headers => true + # Not needed, but run_codegen expects this to be set. folly_config = get_folly_config() run_codegen!( app_path, @@ -193,15 +211,6 @@ def use_react_native! ( :folly_version => folly_config[:version] ) - pod 'ReactCodegen', :path => $CODEGEN_OUTPUT_DIR, :modular_headers => true - pod 'ReactAppDependencyProvider', :path => $CODEGEN_OUTPUT_DIR, :modular_headers => true - - # Always need fabric to access the RCTSurfacePresenterBridgeAdapter which allow to enable the RuntimeScheduler - # If the New Arch is turned off, we will use the Old Renderer, though. - # RNTester always installed Fabric, this change is required to make the template work. - setup_fabric!(:react_native_path => prefix) - setup_bridgeless!(:react_native_path => prefix, :use_hermes => hermes_enabled) - pods_to_update = LocalPodspecPatch.pods_to_update(:react_native_path => prefix) if !pods_to_update.empty? if Pod::Lockfile.public_instance_methods.include?(:detect_changes_with_podfile) diff --git a/packages/react-native/third-party-podspecs/ReactNativeDependencies.podspec b/packages/react-native/third-party-podspecs/ReactNativeDependencies.podspec index c259def49c3e64..32ebe58e05f46f 100644 --- a/packages/react-native/third-party-podspecs/ReactNativeDependencies.podspec +++ b/packages/react-native/third-party-podspecs/ReactNativeDependencies.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |spec| 'WARNING_CFLAGS' => '-Wno-comma -Wno-shorten-64-to-32', } - spec.source = source + spec.source = source spec.preserve_paths = '**/*.*' spec.vendored_frameworks = 'framework/packages/react-native/ReactNativeDependencies.xcframework' spec.header_mappings_dir = 'Headers' @@ -49,6 +49,19 @@ Pod::Spec.new do |spec| mkdir -p Headers XCFRAMEWORK_PATH=$(find "$CURRENT_PATH" -type d -name "ReactNativeDependencies.xcframework") HEADERS_PATH=$(find "$XCFRAMEWORK_PATH" -type d -name "Headers" | head -n 1) + + # Check if XCFRAMEWORK_PATH is empty + if [ -z "$XCFRAMEWORK_PATH" ]; then + echo "ERROR: XCFRAMEWORK_PATH is empty." + exit 0 + fi + + # Check if HEADERS_PATH is empty + if [ -z "$HEADERS_PATH" ]; then + echo "ERROR: HEADERS_PATH is empty." + exit 0 + fi + cp -R "$HEADERS_PATH/" Headers mkdir -p framework/packages/react-native cp -R "$XCFRAMEWORK_PATH/.." framework/packages/react-native/