react-native 0.87.0-rc.1 → 0.87.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Core/InitializeCore.js +8 -1
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/ReactNative/AppRegistry.flow.js +1 -0
- package/Libraries/ReactNative/AppRegistryImpl.js +2 -3
- package/React/Base/RCTVersion.m +1 -1
- package/React/I18n/RCTLocalizedString.mm +38 -2
- package/React-Core-prebuilt.podspec +45 -17
- package/React-Core.podspec +9 -2
- package/ReactAndroid/external-artifacts/build.gradle.kts +49 -0
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SynchronousMountItem.kt +8 -2
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/package.json +10 -8
- package/react-native.config.js +81 -0
- package/scripts/cocoapods/fabric.rb +1 -1
- package/scripts/cocoapods/rncore.rb +35 -78
- package/scripts/cocoapods/rncore_facades.rb +232 -0
- package/scripts/cocoapods/rndependencies.rb +64 -3
- package/scripts/cocoapods/rndeps_facades.rb +193 -0
- package/scripts/cocoapods/spm.rb +78 -11
- package/scripts/codegen/templates/Package.swift.spm-template +97 -0
- package/scripts/react-native-xcode.sh +20 -0
- package/scripts/react_native_pods.rb +65 -16
- package/scripts/replace-rncore-version.js +53 -6
- package/scripts/setup-apple-spm.js +1165 -0
- package/scripts/spm/__doc__/rfc-spm-xcframework.md +707 -0
- package/scripts/spm/__doc__/spm-autolinking-plugins.md +244 -0
- package/scripts/spm/__doc__/spm-header-paths-contract.md +97 -0
- package/scripts/spm/__doc__/spm-plugins-assessment.md +128 -0
- package/scripts/spm/__doc__/spm-scripts.md +451 -0
- package/scripts/spm/autolinking-plugins.js +331 -0
- package/scripts/spm/download-spm-artifacts.js +1409 -0
- package/scripts/spm/expand-spm-dependencies.js +216 -0
- package/scripts/spm/flavored-frameworks.js +1008 -0
- package/scripts/spm/generate-spm-autolinking-config.js +161 -0
- package/scripts/spm/generate-spm-autolinking.js +1888 -0
- package/scripts/spm/generate-spm-package.js +302 -0
- package/scripts/spm/generate-spm-xcodeproj.js +2224 -0
- package/scripts/spm/read-podspec.js +695 -0
- package/scripts/spm/scaffold-package-swift.js +1206 -0
- package/scripts/spm/spm-pbxproj.js +654 -0
- package/scripts/spm/spm-types.js +517 -0
- package/scripts/spm/spm-utils.js +645 -0
- package/scripts/spm/sync-spm-autolinking.js +160 -0
- package/sdks/.hermesv1version +1 -0
- package/sdks/hermes-engine/utils/replace_hermes_version.js +18 -4
- package/sdks/hermes-engine/version.properties +1 -1
- package/third-party-podspecs/ReactNativeDependencies.podspec +2 -2
- package/types_generated/Libraries/ReactNative/AppRegistry.flow.d.ts +2 -2
- package/Libraries/Utilities/SceneTracker.js +0 -42
|
@@ -11,30 +11,16 @@ require_relative './utils.rb'
|
|
|
11
11
|
|
|
12
12
|
### Adds ReactNativeCore-prebuilt as a dependency to the given podspec if we're not
|
|
13
13
|
### building ReactNativeCore from source (then this function does nothing).
|
|
14
|
+
###
|
|
15
|
+
### `<React/...>` resolves through the vendored React.framework; every other namespace
|
|
16
|
+
### (`<react/...>`, `<yoga/...>`, `<hermes/...>`, ...) resolves through the flattened
|
|
17
|
+
### ReactNativeHeaders headers that React-Core-prebuilt exposes. The header search path
|
|
18
|
+
### and the ReactNativeHeaders module-map activation are NOT added here: they are applied
|
|
19
|
+
### post-install by configure_aggregate_xcconfig, which covers aggregate, third-party AND
|
|
20
|
+
### these pods from a single injection site. No clang VFS overlay.
|
|
14
21
|
def add_rncore_dependency(s)
|
|
15
22
|
if !ReactNativeCoreUtils.build_rncore_from_source()
|
|
16
|
-
# Add the dependency
|
|
17
23
|
s.dependency "React-Core-prebuilt"
|
|
18
|
-
|
|
19
|
-
current_pod_target_xcconfig = s.to_hash["pod_target_xcconfig"] || {}
|
|
20
|
-
current_pod_target_xcconfig = current_pod_target_xcconfig.to_h unless current_pod_target_xcconfig.is_a?(Hash)
|
|
21
|
-
|
|
22
|
-
# Add VFS overlay flags for both Objective-C and Swift
|
|
23
|
-
# The VFS overlay file is pre-resolved at pod install time for each platform slice.
|
|
24
|
-
# We reference it directly in the xcframework using the React-VFS.yaml file that
|
|
25
|
-
# is written to the React-Core-prebuilt folder during setup_vfs_overlay.
|
|
26
|
-
# See scripts/ios-prebuild/__docs__/README.md for more details on VFS overlays.
|
|
27
|
-
vfs_overlay_flag = "-ivfsoverlay $(PODS_ROOT)/React-Core-prebuilt/React-VFS.yaml"
|
|
28
|
-
current_pod_target_xcconfig["OTHER_CFLAGS"] ||= "$(inherited)"
|
|
29
|
-
current_pod_target_xcconfig["OTHER_CFLAGS"] += " #{vfs_overlay_flag}"
|
|
30
|
-
current_pod_target_xcconfig["OTHER_CPLUSPLUSFLAGS"] ||= "$(inherited)"
|
|
31
|
-
current_pod_target_xcconfig["OTHER_CPLUSPLUSFLAGS"] += " #{vfs_overlay_flag}"
|
|
32
|
-
# For Swift, we need to use -Xcc to pass flags to the underlying Clang compiler
|
|
33
|
-
# Both the flag and its argument need separate -Xcc prefixes
|
|
34
|
-
current_pod_target_xcconfig["OTHER_SWIFT_FLAGS"] ||= "$(inherited)"
|
|
35
|
-
current_pod_target_xcconfig["OTHER_SWIFT_FLAGS"] += " -Xcc -ivfsoverlay -Xcc $(PODS_ROOT)/React-Core-prebuilt/React-VFS.yaml"
|
|
36
|
-
|
|
37
|
-
s.pod_target_xcconfig = current_pod_target_xcconfig
|
|
38
24
|
end
|
|
39
25
|
end
|
|
40
26
|
|
|
@@ -521,71 +507,36 @@ class ReactNativeCoreUtils
|
|
|
521
507
|
return latest_nightly
|
|
522
508
|
end
|
|
523
509
|
|
|
524
|
-
#
|
|
525
|
-
#
|
|
510
|
+
# Single post-install injection site for the prebuilt header resolution. Adds the
|
|
511
|
+
# ReactNativeHeaders search path + module-map activation to the aggregate (main app)
|
|
512
|
+
# target AND every pod target — RN core pods, third-party pods alike. (add_rncore_dependency
|
|
513
|
+
# only declares the React-Core-prebuilt dependency; it no longer touches xcconfigs.)
|
|
526
514
|
#
|
|
527
|
-
#
|
|
528
|
-
#
|
|
529
|
-
#
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
prebuilt_path = File.join(Pod::Config.instance.project_pods_root, "React-Core-prebuilt")
|
|
534
|
-
xcframework_path = File.join(prebuilt_path, "React.xcframework")
|
|
535
|
-
vfs_template_path = File.join(xcframework_path, "React-VFS-template.yaml")
|
|
536
|
-
|
|
537
|
-
unless File.exist?(vfs_template_path)
|
|
538
|
-
rncore_log("VFS overlay template not found at #{vfs_template_path}", :error)
|
|
539
|
-
exit 1
|
|
540
|
-
end
|
|
541
|
-
|
|
542
|
-
rncore_log("Processing VFS overlay file...")
|
|
543
|
-
|
|
544
|
-
# Read the template content
|
|
545
|
-
vfs_template_content = File.read(vfs_template_path)
|
|
546
|
-
|
|
547
|
-
# Write the VFS file - use the top-level xcframework path
|
|
548
|
-
# so that ${ROOT_PATH}/Headers points to the xcframework's Headers folder
|
|
549
|
-
resolved_vfs_content = vfs_template_content.gsub('${ROOT_PATH}', xcframework_path)
|
|
550
|
-
resolved_vfs_path = File.join(prebuilt_path, "React-VFS.yaml")
|
|
551
|
-
File.write(resolved_vfs_path, resolved_vfs_content)
|
|
552
|
-
rncore_log(" Created VFS overlay at #{resolved_vfs_path}")
|
|
553
|
-
|
|
554
|
-
rncore_log("VFS overlay setup complete")
|
|
555
|
-
end
|
|
556
|
-
|
|
557
|
-
# Configures the xcconfig files for aggregate (main app) targets to enable VFS overlay for React Native Core.
|
|
558
|
-
# This is needed because the main app target does not go through podspec processing,
|
|
559
|
-
# so it won't get the VFS overlay flags from add_rncore_dependency.
|
|
515
|
+
# `<React/...>` resolves through the vendored React.framework; this adds the search
|
|
516
|
+
# path to the flattened ReactNativeHeaders headers (every other RN namespace —
|
|
517
|
+
# the third-party deps namespaces are served by the ReactNativeDependencies pod,
|
|
518
|
+
# see ReactNativeDependenciesUtils.configure_aggregate_xcconfig). There is
|
|
519
|
+
# no clang VFS overlay.
|
|
560
520
|
#
|
|
561
521
|
# Parameters:
|
|
562
522
|
# - installer: The CocoaPods installer object
|
|
563
523
|
def self.configure_aggregate_xcconfig(installer)
|
|
564
524
|
return if @@build_from_source
|
|
565
525
|
|
|
566
|
-
prebuilt_path = File.join(Pod::Config.instance.project_pods_root, "React-Core-prebuilt")
|
|
567
|
-
vfs_overlay_path = File.join(prebuilt_path, "React-VFS.yaml")
|
|
568
|
-
|
|
569
|
-
unless File.exist?(vfs_overlay_path)
|
|
570
|
-
rncore_log("VFS overlay not found at #{vfs_overlay_path}, skipping prebuilt xcconfig configuration", :error)
|
|
571
|
-
exit 1
|
|
572
|
-
end
|
|
573
|
-
|
|
574
526
|
rncore_log("Configuring xcconfig for prebuilt React Native Core...")
|
|
575
527
|
|
|
576
|
-
|
|
577
|
-
swift_vfs_overlay_flag = " -Xcc -ivfsoverlay -Xcc \"#{vfs_overlay_path}\""
|
|
528
|
+
headers_search_path = " \"$(PODS_ROOT)/React-Core-prebuilt/Headers\""
|
|
578
529
|
|
|
579
|
-
# Add
|
|
530
|
+
# Add the header search path to aggregate target xcconfigs (used by the main app target)
|
|
580
531
|
installer.aggregate_targets.each do |aggregate_target|
|
|
581
532
|
aggregate_target.xcconfigs.each do |config_name, config_file|
|
|
582
|
-
|
|
533
|
+
add_prebuilt_header_search_paths(config_file.attributes, headers_search_path)
|
|
583
534
|
xcconfig_path = aggregate_target.xcconfig_path(config_name)
|
|
584
535
|
config_file.save_as(xcconfig_path)
|
|
585
536
|
end
|
|
586
537
|
end
|
|
587
538
|
|
|
588
|
-
# Add
|
|
539
|
+
# Add the header search path to ALL pod targets (for third-party pods that don't call add_rncore_dependency)
|
|
589
540
|
installer.pod_targets.each do |pod_target|
|
|
590
541
|
pod_target.build_settings.each do |config_name, build_settings|
|
|
591
542
|
xcconfig_path = pod_target.xcconfig_path(config_name)
|
|
@@ -593,11 +544,11 @@ class ReactNativeCoreUtils
|
|
|
593
544
|
|
|
594
545
|
xcconfig = Xcodeproj::Config.new(xcconfig_path)
|
|
595
546
|
|
|
596
|
-
#
|
|
597
|
-
|
|
598
|
-
next if
|
|
547
|
+
# Skip if the prebuilt header search path is already present
|
|
548
|
+
header_search_paths = xcconfig.attributes["HEADER_SEARCH_PATHS"] || ""
|
|
549
|
+
next if header_search_paths.include?("React-Core-prebuilt/Headers")
|
|
599
550
|
|
|
600
|
-
|
|
551
|
+
add_prebuilt_header_search_paths(xcconfig.attributes, headers_search_path)
|
|
601
552
|
xcconfig.save_as(xcconfig_path)
|
|
602
553
|
end
|
|
603
554
|
end
|
|
@@ -605,12 +556,18 @@ class ReactNativeCoreUtils
|
|
|
605
556
|
rncore_log("Prebuilt xcconfig configuration complete")
|
|
606
557
|
end
|
|
607
558
|
|
|
608
|
-
# Helper method to add
|
|
609
|
-
def self.
|
|
610
|
-
ReactNativePodsUtils.add_flag_to_map_with_inheritance(attributes, "
|
|
611
|
-
ReactNativePodsUtils.add_flag_to_map_with_inheritance(attributes, "OTHER_CPLUSPLUSFLAGS", vfs_overlay_flag)
|
|
612
|
-
ReactNativePodsUtils.add_flag_to_map_with_inheritance(attributes, "OTHER_SWIFT_FLAGS", swift_vfs_overlay_flag)
|
|
559
|
+
# Helper method to add the prebuilt ReactNativeHeaders header search path to an xcconfig attributes map
|
|
560
|
+
def self.add_prebuilt_header_search_paths(attributes, headers_search_path)
|
|
561
|
+
ReactNativePodsUtils.add_flag_to_map_with_inheritance(attributes, "HEADER_SEARCH_PATHS", headers_search_path)
|
|
613
562
|
# Suppress incomplete umbrella warnings for the prebuilt frameworks (it is expected, as our umbrella headers do not include all headers)
|
|
614
563
|
ReactNativePodsUtils.add_flag_to_map_with_inheritance(attributes, "OTHER_SWIFT_FLAGS", " -Xcc -Wno-incomplete-umbrella")
|
|
564
|
+
# Activate the ReactNativeHeaders module map so the relocated namespaces
|
|
565
|
+
# (`yoga`, `RCTDeprecation`, `ReactNativeHeaders_react`, ...) are modular —
|
|
566
|
+
# otherwise the React framework's clang explicit-module precompile trips
|
|
567
|
+
# -Wnon-modular-include-in-framework-module on `<yoga/...>` / `<react/...>`.
|
|
568
|
+
# Quoted so a $(PODS_ROOT) containing spaces stays a single clang argument.
|
|
569
|
+
module_map_flag = " \"-fmodule-map-file=$(PODS_ROOT)/React-Core-prebuilt/Headers/module.modulemap\""
|
|
570
|
+
ReactNativePodsUtils.add_flag_to_map_with_inheritance(attributes, "OTHER_CFLAGS", module_map_flag)
|
|
571
|
+
ReactNativePodsUtils.add_flag_to_map_with_inheritance(attributes, "OTHER_SWIFT_FLAGS", " -Xcc" + module_map_flag)
|
|
615
572
|
end
|
|
616
573
|
end
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
#
|
|
3
|
+
# This source code is licensed under the MIT license found in the
|
|
4
|
+
# LICENSE file in the root directory of this source tree.
|
|
5
|
+
|
|
6
|
+
require 'json'
|
|
7
|
+
require 'fileutils'
|
|
8
|
+
|
|
9
|
+
# Facade podspecs for the prebuilt React Native Core path.
|
|
10
|
+
#
|
|
11
|
+
# In prebuilt mode the compiled code AND headers for the React core pods live
|
|
12
|
+
# entirely inside React.xcframework + React-Core-prebuilt (which flattens the
|
|
13
|
+
# ReactNativeHeaders namespaces into its Headers/). Re-installing the SOURCE
|
|
14
|
+
# podspecs in that mode is what makes them ship duplicate headers that shadow the
|
|
15
|
+
# prebuilt artifact (via HEADER_SEARCH_PATHS, CocoaPods .hmap header maps, and
|
|
16
|
+
# the all-product-headers VFS overlay) and break the React framework's clang
|
|
17
|
+
# explicit-module precompile.
|
|
18
|
+
#
|
|
19
|
+
# Instead we install dependency-only FACADE podspecs for those names: they ship
|
|
20
|
+
# no source files and (with one narrow exception, see FACADE_REEXPOSED_HEADERS)
|
|
21
|
+
# no headers, so CocoaPods makes them PBXAggregateTarget
|
|
22
|
+
# placeholders (should_build? == false) and nothing is laid down to shadow. Each
|
|
23
|
+
# facade depends on React-Core-prebuilt so its consumers transitively pick up the
|
|
24
|
+
# prebuilt framework + headers. The pod NAMES still resolve, so ReactCodegen,
|
|
25
|
+
# third-party modules, and RN's own podspec graph keep resolving `React-Core`,
|
|
26
|
+
# `Yoga`, `React-Core/Default`, etc.
|
|
27
|
+
#
|
|
28
|
+
# MAINTENANCE MODEL: the set of facaded pods is explicit (FACADE_PODS) so the
|
|
29
|
+
# prebuilt rollout can be staged, but each facade's VERSION and SUBSPECS are
|
|
30
|
+
# DERIVED from the real podspec at `pod install` time (Pod::Specification.from_file).
|
|
31
|
+
# That removes the drift risk that would otherwise bite third-party libraries:
|
|
32
|
+
# if React adds/renames `React-Core/<Subspec>`, the facade exposes it
|
|
33
|
+
# automatically — nobody has to hand-maintain a parallel subspec list.
|
|
34
|
+
#
|
|
35
|
+
# This is staged: phase 1 facades a small set and KEEPS the existing
|
|
36
|
+
# podspec_sources / add_rncore_dependency / configure_aggregate_xcconfig /
|
|
37
|
+
# -fmodule-map-file machinery. The set is expanded until the cold prebuilt
|
|
38
|
+
# build passes; the distributed prebuilt helpers are only deleted afterwards.
|
|
39
|
+
module RNCoreFacades
|
|
40
|
+
# pod name => podspec path (relative to the react-native package root).
|
|
41
|
+
# These are the React-core pods whose code + headers are fully provided by
|
|
42
|
+
# the prebuilt React.xcframework / React-Core-prebuilt. Start small; expand as
|
|
43
|
+
# the cold build surfaces more shadowing pods. (NOTE: not every caller of
|
|
44
|
+
# add_rncore_dependency belongs here — e.g. ReactCodegen depends on the
|
|
45
|
+
# prebuilt but still builds its own generated sources, so it is NOT a facade.)
|
|
46
|
+
FACADE_PODS = {
|
|
47
|
+
"React-Core" => "React-Core.podspec",
|
|
48
|
+
"React-RCTFabric" => "React/React-RCTFabric.podspec",
|
|
49
|
+
"React-RCTRuntime" => "React/Runtime/React-RCTRuntime.podspec",
|
|
50
|
+
"Yoga" => "ReactCommon/yoga/Yoga.podspec",
|
|
51
|
+
"RCTDeprecation" => "ReactApple/Libraries/RCTFoundation/RCTDeprecation/RCTDeprecation.podspec",
|
|
52
|
+
"FBLazyVector" => "Libraries/FBLazyVector/FBLazyVector.podspec",
|
|
53
|
+
"RCTRequired" => "Libraries/Required/RCTRequired.podspec",
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# A facade ships NO headers by default — the prebuilt React.framework /
|
|
57
|
+
# React-Core-prebuilt own them. NARROW EXCEPTION: a few headers live ONLY
|
|
58
|
+
# inside React.framework/Headers (served angle-only as <React/...>, e.g.
|
|
59
|
+
# because they reach unguarded C++ and are excluded from the framework module
|
|
60
|
+
# map) and are NOT in the flattened React-Core-prebuilt/Headers. A quoted
|
|
61
|
+
# `#import "<name>.h"` therefore has no resolution target in prebuilt mode.
|
|
62
|
+
#
|
|
63
|
+
# Community Fabric modules quote-import RCTFabricComponentsPlugins.h (47x in a
|
|
64
|
+
# full app: slider, maps, pager-view, keyboard-controller, ...). In source it
|
|
65
|
+
# was vended by React-RCTFabric at header_dir "React", which put it in
|
|
66
|
+
# dependents' CocoaPods header maps so the bare quoted name resolved. The
|
|
67
|
+
# facade dropped it. We re-vend JUST that header here so dependents' header
|
|
68
|
+
# maps carry it again, exactly as the source pod did.
|
|
69
|
+
#
|
|
70
|
+
# Re-exposing a SINGLE header (not the whole React/ namespace) does not put
|
|
71
|
+
# <react/...>/<yoga/...> on -I, so it does NOT reintroduce the
|
|
72
|
+
# -Wnon-modular-include-in-framework-module shadowing the modular prebuilt
|
|
73
|
+
# layout exists to eliminate. The header is core-only (matches source: it
|
|
74
|
+
# only ever declared RN's built-in components; third-party Fabric components
|
|
75
|
+
# register via the codegen RCTThirdPartyComponentsProvider, shipped by the
|
|
76
|
+
# non-facaded ReactCodegen pod).
|
|
77
|
+
#
|
|
78
|
+
# pod name => { "header_dir" => <dir>, "globs" => [<glob rel. to its podspec dir>] }
|
|
79
|
+
FACADE_REEXPOSED_HEADERS = {
|
|
80
|
+
"React-RCTFabric" => {
|
|
81
|
+
"header_dir" => "React",
|
|
82
|
+
"globs" => ["Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.h"],
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Sub-directory (relative to the install root) that holds the generated facades.
|
|
87
|
+
FACADE_RELDIR = File.join("build", "rncore-facades")
|
|
88
|
+
|
|
89
|
+
@@install_root = nil
|
|
90
|
+
|
|
91
|
+
# True when `name` should be installed as a facade instead of its source podspec.
|
|
92
|
+
def self.facade?(name)
|
|
93
|
+
FACADE_PODS.key?(name)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Generates the facade podspecs and returns the base directory holding them.
|
|
97
|
+
# Each facade gets its OWN sub-directory containing a single
|
|
98
|
+
# `<Name>.podspec.json`, so it can be installed as a LOCAL pod via
|
|
99
|
+
# `:path => <dir>`. `:path` (PathSource) uses the spec in place and never
|
|
100
|
+
# downloads `spec.source` — unlike `:podspec` (PodspecSource), which is an
|
|
101
|
+
# *external* source whose `root_spec.source` CocoaPods would actually fetch
|
|
102
|
+
# (i.e. git-clone react-native for every empty facade). Idempotent; safe to
|
|
103
|
+
# call once per `pod install`.
|
|
104
|
+
#
|
|
105
|
+
# `react_native_path` locates the real podspecs we mirror. version + subspecs +
|
|
106
|
+
# default_subspecs are DERIVED from the real spec so the facade stays
|
|
107
|
+
# graph-equivalent to the source pod (resources are NOT carried — they live in
|
|
108
|
+
# the prebuilt artifact; see the note in the loop). A facaded pod whose real
|
|
109
|
+
# podspec can't be read is a hard error (see load_real_spec) — silently shipping
|
|
110
|
+
# an empty facade would hide exactly the drift this guards against.
|
|
111
|
+
def self.generate(react_native_path, install_root, version, ios_version)
|
|
112
|
+
@@install_root = install_root.to_s
|
|
113
|
+
abs_base = File.join(@@install_root, FACADE_RELDIR)
|
|
114
|
+
FileUtils.mkdir_p(abs_base)
|
|
115
|
+
FACADE_PODS.each do |name, podspec_rel_path|
|
|
116
|
+
podspec_path = File.join(react_native_path.to_s, podspec_rel_path)
|
|
117
|
+
podspec_dir = File.dirname(podspec_path)
|
|
118
|
+
real = load_real_spec(podspec_path, name)
|
|
119
|
+
dir = File.join(abs_base, name)
|
|
120
|
+
FileUtils.mkdir_p(dir)
|
|
121
|
+
|
|
122
|
+
spec = {
|
|
123
|
+
"name" => name,
|
|
124
|
+
"version" => real.version.to_s,
|
|
125
|
+
"summary" => "Prebuilt facade for #{name} (code + headers live in React-Core-prebuilt).",
|
|
126
|
+
"homepage" => "https://reactnative.dev/",
|
|
127
|
+
"license" => "MIT",
|
|
128
|
+
"authors" => "Meta Platforms, Inc. and its affiliates",
|
|
129
|
+
"platforms" => { "ios" => ios_version },
|
|
130
|
+
# Required podspec attribute, but never fetched: the pod is installed
|
|
131
|
+
# as a LOCAL pod (`:path => <dir>`), which uses this spec in place and
|
|
132
|
+
# ships no source_files. Placeholder only.
|
|
133
|
+
"source" => { "git" => "https://github.com/facebook/react-native.git" },
|
|
134
|
+
"dependencies" => { "React-Core-prebuilt" => [] },
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
# NOTE: the facade carries NO resources. The pods' non-code resources
|
|
138
|
+
# (e.g. the privacy manifest) are embedded directly in the prebuilt
|
|
139
|
+
# React.xcframework by the ios-prebuild compose (see ios-prebuild/framework-resources.js),
|
|
140
|
+
# so they reach both CocoaPods-prebuilt and SwiftPM from the artifact —
|
|
141
|
+
# the facade only needs to declare the React-Core-prebuilt dependency.
|
|
142
|
+
|
|
143
|
+
# Re-vend the narrow set of angle-only framework headers that community
|
|
144
|
+
# modules quote-import (see FACADE_REEXPOSED_HEADERS). The header is
|
|
145
|
+
# COPIED into the facade dir (a self-contained snapshot — robust, no
|
|
146
|
+
# `..` globs reaching out of the pod) and exposed as a public header.
|
|
147
|
+
# It's header-only (a `.h` has nothing to compile, so the facade stays
|
|
148
|
+
# a placeholder), but CocoaPods lays it into
|
|
149
|
+
# Pods/Headers/Public/<Name>/<header_dir>/ and dependents' .hmap,
|
|
150
|
+
# restoring quoted resolution exactly as the source pod did.
|
|
151
|
+
reexposed = FACADE_REEXPOSED_HEADERS[name]
|
|
152
|
+
if reexposed
|
|
153
|
+
copied = copy_reexposed_headers(reexposed["globs"], podspec_dir, dir, name)
|
|
154
|
+
unless copied.empty?
|
|
155
|
+
spec["source_files"] = copied
|
|
156
|
+
spec["public_header_files"] = copied
|
|
157
|
+
spec["header_dir"] = reexposed["header_dir"] if reexposed["header_dir"]
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Preserve default_subspec so a bare `pod '<Name>'` resolves to the SAME
|
|
162
|
+
# subspec graph as the source pod (without it CocoaPods pulls every
|
|
163
|
+
# subspec, which is not graph-equivalent).
|
|
164
|
+
defaults = Array(real.default_subspecs)
|
|
165
|
+
spec["default_subspecs"] = defaults unless defaults.empty?
|
|
166
|
+
|
|
167
|
+
subspecs = derive_subspecs(real)
|
|
168
|
+
unless subspecs.empty?
|
|
169
|
+
spec["subspecs"] = subspecs.map do |ss|
|
|
170
|
+
{ "name" => ss, "dependencies" => { "React-Core-prebuilt" => [] } }
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
File.write(File.join(dir, "#{name}.podspec.json"), JSON.pretty_generate(spec))
|
|
175
|
+
end
|
|
176
|
+
abs_base
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Facade dir for `<name>`, RELATIVE to the install root — pass to `pod :path =>`.
|
|
180
|
+
# Relative (not absolute) so the path CocoaPods records in Podfile.lock is
|
|
181
|
+
# portable rather than machine-specific.
|
|
182
|
+
def self.facade_path(name)
|
|
183
|
+
File.join(FACADE_RELDIR, name)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Loads the real podspec so we can mirror its structure. A facaded pod MUST have
|
|
187
|
+
# a readable real podspec — if it's missing or unparseable we raise rather than
|
|
188
|
+
# ship an empty facade, since that would silently drop subspecs (the very drift
|
|
189
|
+
# this mechanism exists to prevent).
|
|
190
|
+
def self.load_real_spec(path, name)
|
|
191
|
+
unless File.exist?(path)
|
|
192
|
+
raise "[RNCoreFacades] Real podspec for facaded pod '#{name}' not found at #{path}. " \
|
|
193
|
+
"Update FACADE_PODS in rncore_facades.rb if the podspec moved."
|
|
194
|
+
end
|
|
195
|
+
Pod::Specification.from_file(path)
|
|
196
|
+
rescue => e
|
|
197
|
+
raise "[RNCoreFacades] Failed to read real podspec for facaded pod '#{name}' at #{path}: #{e.message}"
|
|
198
|
+
end
|
|
199
|
+
private_class_method :load_real_spec
|
|
200
|
+
|
|
201
|
+
# Library (non-test, non-app) subspec names of the real spec, so third-party
|
|
202
|
+
# libs depending on `<pod>/<subspec>` keep resolving. Derived, never hand-listed.
|
|
203
|
+
def self.derive_subspecs(real)
|
|
204
|
+
real.subspecs
|
|
205
|
+
.reject { |ss| ss.test_specification? || (ss.respond_to?(:app_specification?) && ss.app_specification?) }
|
|
206
|
+
.map(&:base_name)
|
|
207
|
+
end
|
|
208
|
+
private_class_method :derive_subspecs
|
|
209
|
+
|
|
210
|
+
# Copy the re-exposed header(s) into the facade dir (flat) and return the
|
|
211
|
+
# facade-relative source_files entries. `globs` are resolved against the real
|
|
212
|
+
# podspec dir. A glob that matches nothing is a hard error: the whole point is
|
|
213
|
+
# to keep a quoted-import header resolvable, so silently shipping a facade
|
|
214
|
+
# without it would reintroduce the exact "file not found" we're fixing.
|
|
215
|
+
def self.copy_reexposed_headers(globs, podspec_dir, facade_dir, name)
|
|
216
|
+
copied = []
|
|
217
|
+
Array(globs).each do |g|
|
|
218
|
+
matches = Dir.glob(File.expand_path(g, podspec_dir))
|
|
219
|
+
if matches.empty?
|
|
220
|
+
raise "[RNCoreFacades] Re-exposed header glob '#{g}' for facade '#{name}' " \
|
|
221
|
+
"matched no files under #{podspec_dir}. Update FACADE_REEXPOSED_HEADERS."
|
|
222
|
+
end
|
|
223
|
+
matches.each do |src|
|
|
224
|
+
base = File.basename(src)
|
|
225
|
+
FileUtils.cp(src, File.join(facade_dir, base))
|
|
226
|
+
copied << base
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
copied.uniq
|
|
230
|
+
end
|
|
231
|
+
private_class_method :copy_reexposed_headers
|
|
232
|
+
end
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
require "json"
|
|
7
7
|
require 'net/http'
|
|
8
8
|
require 'rexml/document'
|
|
9
|
+
require 'shellwords'
|
|
9
10
|
|
|
10
11
|
require_relative './utils.rb'
|
|
11
12
|
|
|
@@ -36,7 +37,7 @@ def add_rn_third_party_dependencies(s)
|
|
|
36
37
|
header_search_paths = current_pod_target_xcconfig["HEADER_SEARCH_PATHS"] || []
|
|
37
38
|
|
|
38
39
|
if header_search_paths.is_a?(String)
|
|
39
|
-
header_search_paths =
|
|
40
|
+
header_search_paths = Shellwords.shellsplit(header_search_paths)
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
header_search_paths << "$(PODS_ROOT)/glog"
|
|
@@ -47,10 +48,24 @@ def add_rn_third_party_dependencies(s)
|
|
|
47
48
|
header_search_paths << "$(PODS_ROOT)/SocketRocket"
|
|
48
49
|
header_search_paths << "$(PODS_ROOT)/RCT-Folly"
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
# uniq so a second call on the same spec can't duplicate entries.
|
|
52
|
+
current_pod_target_xcconfig["HEADER_SEARCH_PATHS"] = header_search_paths.uniq
|
|
51
53
|
else
|
|
54
|
+
# Prebuilt-deps mode: this pod SELF-SERVES the third-party headers from its
|
|
55
|
+
# own xcframework (incl. SocketRocket - sole supplier in this mode). See
|
|
56
|
+
# scripts/cocoapods/__docs__/prebuilt-deps.md for the full contract.
|
|
52
57
|
s.dependency "ReactNativeDependencies"
|
|
53
|
-
|
|
58
|
+
|
|
59
|
+
header_search_paths = current_pod_target_xcconfig["HEADER_SEARCH_PATHS"] || []
|
|
60
|
+
if header_search_paths.is_a?(String)
|
|
61
|
+
header_search_paths = Shellwords.shellsplit(header_search_paths)
|
|
62
|
+
end
|
|
63
|
+
# Artifact headers are flattened into the pod-local Headers/ by the podspec
|
|
64
|
+
# prepare_command (see __docs__/prebuilt-deps.md).
|
|
65
|
+
header_search_paths << "$(PODS_ROOT)/ReactNativeDependencies/Headers"
|
|
66
|
+
|
|
67
|
+
# uniq so a second call on the same spec can't duplicate entries.
|
|
68
|
+
current_pod_target_xcconfig["HEADER_SEARCH_PATHS"] = header_search_paths.uniq
|
|
54
69
|
end
|
|
55
70
|
|
|
56
71
|
s.pod_target_xcconfig = current_pod_target_xcconfig
|
|
@@ -139,6 +154,52 @@ class ReactNativeDependenciesUtils
|
|
|
139
154
|
end
|
|
140
155
|
end
|
|
141
156
|
|
|
157
|
+
# Single post-install injection site for the prebuilt deps header resolution.
|
|
158
|
+
# Adds the flattened ReactNativeDependencies/Headers search path to the
|
|
159
|
+
# aggregate (main app) target AND every pod target, mirroring
|
|
160
|
+
# ReactNativeCoreUtils.configure_aggregate_xcconfig. ReactNativeHeaders is
|
|
161
|
+
# pure-RN, so this path is the single global home of the third-party
|
|
162
|
+
# namespaces (folly/glog/boost/fmt/double-conversion/fast_float/
|
|
163
|
+
# SocketRocket): pods that never call add_rn_third_party_dependencies (nor
|
|
164
|
+
# depend on a facade) still compile RN headers that textually reach
|
|
165
|
+
# <folly/...>. No module-map activation needed — the deps headers are
|
|
166
|
+
# served textually; modules come from the ReactNativeDependencies pod.
|
|
167
|
+
def self.configure_aggregate_xcconfig(installer)
|
|
168
|
+
return if @@build_from_source
|
|
169
|
+
|
|
170
|
+
rndeps_log("Configuring xcconfig for prebuilt React Native Dependencies...")
|
|
171
|
+
headers_search_path = " \"$(PODS_ROOT)/ReactNativeDependencies/Headers\""
|
|
172
|
+
|
|
173
|
+
# Add the header search path to aggregate target xcconfigs (used by the main app target)
|
|
174
|
+
installer.aggregate_targets.each do |aggregate_target|
|
|
175
|
+
aggregate_target.xcconfigs.each do |config_name, config_file|
|
|
176
|
+
ReactNativePodsUtils.add_flag_to_map_with_inheritance(config_file.attributes, "HEADER_SEARCH_PATHS", headers_search_path)
|
|
177
|
+
xcconfig_path = aggregate_target.xcconfig_path(config_name)
|
|
178
|
+
config_file.save_as(xcconfig_path)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Add the header search path to ALL pod targets (for pods that don't go
|
|
183
|
+
# through add_rn_third_party_dependencies)
|
|
184
|
+
installer.pod_targets.each do |pod_target|
|
|
185
|
+
pod_target.build_settings.each do |config_name, build_settings|
|
|
186
|
+
xcconfig_path = pod_target.xcconfig_path(config_name)
|
|
187
|
+
next unless File.exist?(xcconfig_path)
|
|
188
|
+
|
|
189
|
+
xcconfig = Xcodeproj::Config.new(xcconfig_path)
|
|
190
|
+
|
|
191
|
+
# Skip if the deps header search path is already present
|
|
192
|
+
header_search_paths = xcconfig.attributes["HEADER_SEARCH_PATHS"] || ""
|
|
193
|
+
next if header_search_paths.include?("ReactNativeDependencies/Headers")
|
|
194
|
+
|
|
195
|
+
ReactNativePodsUtils.add_flag_to_map_with_inheritance(xcconfig.attributes, "HEADER_SEARCH_PATHS", headers_search_path)
|
|
196
|
+
xcconfig.save_as(xcconfig_path)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
rndeps_log("Prebuilt deps xcconfig configuration complete")
|
|
201
|
+
end
|
|
202
|
+
|
|
142
203
|
def self.podspec_source_download_prebuild_release_tarball()
|
|
143
204
|
# Warn if @@react_native_path is not set
|
|
144
205
|
if @@react_native_path == ""
|