Summary:
I discovered that 0.69 could run React Native as Dynamic framework with Hermes and starting from 0.70 that's not possible anymore.
This diff restore that possibility.
Notice that now Hermes provisdes JSI and Dynamic Frameworks requires that all the dependencies are explicitly defined, therefore, whenever we have a pod that depended on `React-jsi`, now it also has to explicitly depends on `hermes-engine`
## Changelog
[iOS][Fixed] - Add Back dynamic framework support for the Old Architecture with Hermes
Reviewed By: cortinico
Differential Revision: D42829728
fbshipit-source-id: a660e3b1e346ec6cf3ceb8771dd8bceb0dbcb13a
Summary:
In 0.71.0-RC.2, we had a regression in `use_frameworks!`.
This brings back JSIDynamic and JSI together because the current setup is not compatible with iOS frameworks
## Changelog
[iOS][Added] - Bring back JSIDynamic and JSI
Reviewed By: cortinico
Differential Revision: D41557823
fbshipit-source-id: 95eb2fe7df69992861396e41d11cd5182193e1a3
# Conflicts:
# ReactCommon/jsi/React-jsidynamic.podspec
Summary:
In 0.71.0-RC.2, we had a regression in `use_frameworks!`.
The `use_frameworks! :linkage => :static` use to work fine with the Old Architecture.
We modified how the `React-bridging` pod is configured and, now those are broken.
This change make sure to use the right imports for React-bridging.
## Changelog
[iOS][Changed] - Fix imports in React Bridging for Old Arch and frameworks
Reviewed By: christophpurrer, cortinico
Differential Revision: D41551103
fbshipit-source-id: 4416fde92fef11eb801daf2302a57fe52732e4ef
Summary:
This change excludes the `LongLivedObject.h` file from the pod in the ReactCommon library.
The file creates a problem when the `use_frameworks!` option is used in an app because there can't be two files with the same name, despite being in different paths,
within the same framework. Specifically, this `LongLivedObject` is just a redirect to the other one, so it should be safe to exclude this.
## Changelog
[iOS][Fixed] - Exclude redirector to `LongLivedObject.h` from ReactCommon podspec
Pull Request resolved: https://github.com/facebook/react-native/pull/35491
Test Plan: 1. Manually tested in an app from RC2
Reviewed By: cortinico
Differential Revision: D41548985
Pulled By: cipolleschi
fbshipit-source-id: acc57fccdedb344a3aa105f2968645a049392e07
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35506
In our build we had a mixture of `_` and `-` to separate targets.
Dashes don't play well with Gradle + as we expose them now via Prefab,
let's stick to use only underscores
Changelog:
[Internal] [Changed] - Rename target to don't use dashes
Reviewed By: cipolleschi
Differential Revision: D41578938
fbshipit-source-id: 8aa44aa2dc7bf4822b45e5044532837b989817d2
Summary:
This is the last library that we should expose via Prefab.
Thanks to cipolleschi 's work here moving the file to `/ReactCommon/jsc` folder
we can easily expose it to be consumed by third parties.
Changelog:
[Internal] [Changed] - Expose `jscruntime` to be consumed via Prefab
Reviewed By: cipolleschi
Differential Revision: D41534564
fbshipit-source-id: fb4b2d801def8caf71638dcb74eb87f8230984d4
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35482
This change moves the JSCRuntime.h/cpp into a `jsc` folder.
This change is required for several reasons:
1. on iOS, the new `jsi`, `jsidynamic` and `jsc` setup is breaking the `use_frameworks!` with `:linkage => :static` option with the old architecture. So it is a regression.
2. JSCRuntime is required by some libraries and needs to be exposed as a prefab and the current setup makes it hard to achieve.
allow-large-files
[General][Changed] - Move JSCRuntime into a separate pod/prefab
Reviewed By: cortinico
Differential Revision: D41533778
fbshipit-source-id: 642240c93a6c124280430d4f196049cb67cb130b
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35457
This exposes `hermes-executor` to be consumed via prefab so that
libraries can depend on it and use its symbols if needed (Expo and Reanimated need it).
Changelog:
[Internal] [Changed] - Expose `hermes-executor` to be consumed via prefab
Reviewed By: cipolleschi
Differential Revision: D41520019
fbshipit-source-id: d590a043ea89fdd8ff41b0ed20900c9cf381a1e4
Summary:
X-link: https://github.com/facebook/yoga/pull/1173
In https://github.com/facebook/react-native/issues/35351 we see incorrect child item height when the flex-wrap is enabled, the cross-axis is to be stretched, and main-axis overflow is caused by gap.
In YGDistributeFreeSpaceSecondPass, if we do not have overflow (determined by flexBasisOverflows), we have stretch cross-alignment, and we reason that nothing can add to main axis dimensions, we know we're a single line and want to take full cross dimensions. and can set YGMeasureModeExactly which uses parent dimensions. Guessing an optimization?
If we do have overflow, then we set YGMeasureModeAtMost to find minimum possible cross-axis dimensions instead.
`flexBasisOverflows` incorporates both computed flex basis, and margin, so it is more generally a flag for whether we will wrap. So we should incorporate gap spacing into it. E.g. it is also used for whether we should the match main axis parent dimension of the overall container. This change does just that, and renames the flag to `mainAxisOverflows`.
We will want to cherry-pick the fix for this into RN 0.71 since we have not yet introduced the community to the incorrect behavior, and we expect a lot of usage of flex-gap.
Changelog:
[General][Fixed] - Fix incorrect height when gap causes main axis to overflow and cross-axis is stretched
Reviewed By: yungsters
Differential Revision: D41311424
fbshipit-source-id: bd0c3b5aac478a56878703b6da84fc3993cc14da
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35212
A previous change - https://github.com/facebook/react-native/pull/34011 - already fixed basic usage of <react/bridging/.../ imports.
However that change was only tailored towards the usage of: <react/bridging/CallbackWrapper.h>
Any other header besides <react/bridging/CallbackWrapper.h> from <react/bridging/... can't be imported at this time in Xcode ... ... which is bad.
For C++ TurboModules we need to be able to access *any* <react/bridging/...> header via the React-Codegen CocoaPod.
Hence adding bridging now as a sub-spec to the ReactCommon CocoaPod
Changelog: [Internal]
Reviewed By: cipolleschi
Differential Revision: D41057878
fbshipit-source-id: 83c117bc5252d84dd419cdb72f145f65547d23b2
# Conflicts:
# scripts/cocoapods/__tests__/codegen_utils-test.rb
Summary:
X-link: https://github.com/facebook/yoga/pull/1173
In https://github.com/facebook/react-native/issues/35351 we see incorrect child item height when the flex-wrap is enabled, the cross-axis is to be stretched, and main-axis overflow is caused by gap.
In YGDistributeFreeSpaceSecondPass, if we do not have overflow (determined by flexBasisOverflows), we have stretch cross-alignment, and we reason that nothing can add to main axis dimensions, we know we're a single line and want to take full cross dimensions. and can set YGMeasureModeExactly which uses parent dimensions. Guessing an optimization?
If we do have overflow, then we set YGMeasureModeAtMost to find minimum possible cross-axis dimensions instead.
`flexBasisOverflows` incorporates both computed flex basis, and margin, so it is more generally a flag for whether we will wrap. So we should incorporate gap spacing into it. E.g. it is also used for whether we should the match main axis parent dimension of the overall container. This change does just that, and renames the flag to `mainAxisOverflows`.
We will want to cherry-pick the fix for this into RN 0.71 since we have not yet introduced the community to the incorrect behavior, and we expect a lot of usage of flex-gap.
Changelog:
[General][Fixed] - Fix incorrect height when gap causes main axis to overflow and cross-axis is stretched
Reviewed By: yungsters
Differential Revision: D41311424
fbshipit-source-id: bd0c3b5aac478a56878703b6da84fc3993cc14da
Summary:
## Context
If React Native is built from *main* of any non-stable commit, then Hermes is built from source. The build is performed by `build-ios-framework.sh` and `build-mac-framework.sh` scripts in `hermes-engine.podspec` `prepare_command` stage. Since those scripts have no access build target information, they build all possible architectures and platforms just in case. That takes ages.
## Solution
The idea is to integrate build script into Xcode *run script* phase, and use build target information to build Hermes for active architecture only.
## Implementation
- Existing behaviour remains unchanged for local tarball and remote prebuild cases.
- `build-hermesc-xcode.sh` builds Hermesc as `hermes-engine.podspec` `prepare_command`. Default build location is `react-native/sdks/hermes-engine/build_host_hermesc`.
- `build-hermes-xcode.sh` builds Hermes in 'Build Hermes' Xcode script phase. It uses `$PLATFORM_NAME`, `$CONFIGURATION`, `$ARCHS`, `$IPHONEOS_DEPLOYMENT_TARGET` and `$MACOSX_DEPLOYMENT_TARGET` environment variables to configure cmake project so it builds only active architecture. The script also gets RN version, *cmake* path and *hermesc* path from the podspec.
- `copy-hermes-xcode.sh` copies Hermes.framework inside the app bundle. This script phase is added to the user app target in a `post_install` hook, after pods are integrated in a user project.
- `OTHER_LDFLAGS -framework "hermes"` added to the user project to enable linking against Hermes.framework.
- If `HERMES_OVERRIDE_HERMESC_PATH` is set, then Hermesc building is skipped, and `HERMES_OVERRIDE_HERMESC_PATH` is used for `build-hermes-xcode.sh`.
- `HERMES_CLI_PATH` is injected into user project config to enable Hermes source maps in `react-native-xcode.sh`.
## Things that didn't work
- *Running build-hermesc-xcode.sh in Xcode run script phase*. This doesn't work because Hermesc is supposed to be built for macos, and if build target is ios, then Xcode configures environment in such a way that Hermesc build fails.
- *Installing Hermesc into CocoaPods download folder*. So it then ends up in `Pods/hermes-engine/build_host_hermesc`, and all the housekeeping is handled by CocoaPods. This doesn't work because cmake uses absolute paths in a configured project. If configured project is moved to a different location, nothing builds.
- *Installing Hermesc directly into Pods/hermes-engine*. This doesn't work because CocoaPods runs prepare_command before Pods folder clean up, and everything gets wiped.
## Known issue
- If `Pods/hermes-engine` is manually removed, then `sdks/hermes-engine/build_host_hermesc` must also be removed before running `pod install`. Otherwise cmake will complain about stale cache:
```
CMake Error: The source "<CocoaPodsCache>/hermes-engine/<hash2>/CMakeLists.txt" does not match the source
"<CocoaPodsCache>/hermes-engine/<has1>/CMakeLists.txt" used to generate cache. Re-run cmake with a different source directory.
```
## Benchmark
MacBook M1 2021 32 GB.
```
export REACT_NATIVE_PATH=~/fbsource/xplat/js/react-native-github
cd $REACT_NATIVE_PATH/packages/rn-tester
pod install
rm -rf $REACT_NATIVE_PATH/sdks/hermes-engine/build_host_hermesc
cd $REACT_NATIVE_PATH/packages/rn-tester/Pods/hermes-engine
echo 't1=$(date +%s); $@; t2=$(date +%s); diff=$(echo "$t2 - $t1" | bc); echo Operation took $diff seconds.' > /tmp/benchmark.sh
```
```
# Before
export BUILD_TYPE=Debug
export JSI_PATH=$REACT_NATIVE_PATH/ReactCommon/jsi
export RELEASE_VERSION=1000.0
export IOS_DEPLOYMENT_TARGET=iphonesimulator
export MAC_DEPLOYMENT_TARGET=12.6
cd $REACT_NATIVE_PATH/packages/rn-tester/Pods/hermes-engine
. /tmp/benchmark.sh $REACT_NATIVE_PATH/sdks/hermes-engine/utils/build-ios-framework.sh
# Operation took 252 seconds
. /tmp/benchmark.sh $REACT_NATIVE_PATH/sdks/hermes-engine/utils/build-mac-framework.sh
# Operation took 179 seconds
```
```
# After
. /tmp/benchmark.sh source $REACT_NATIVE_PATH/sdks/hermes-engine/utils/build-hermesc-xcode.sh $REACT_NATIVE_PATH/sdks/hermes-engine/build_host_hermesc
# Operation took 59 seconds.
. /tmp/benchmark.sh xcodebuild -workspace $REACT_NATIVE_PATH/packages/rn-tester/RNTesterPods.xcworkspace -scheme hermes-engine
# Operation took 106 seconds.
```
|Before|||After|||
|--|
|iOS framework (s)|Mac framework (s)|Total (s)|Hermesc (s)|Target-specific framework (s)|Total (s)|
|252|179|431|59|106|**165 (-266) (-61%)**|
The performance win is fixed, and does not depend on the project size and structure.
As an example, this is how these changes affect build time of RNTester.
|Before||||After|||
|--|
||Pod install (s)|Xcode build (s)|Total (s)|Pod install (s)|Xcode build (s)|Total (s)|
|Clean build|1219|132|1352|734 (-485)|249(+117)|**983 (-369)**|
|Incremental build|82|30|112|105 (+23)|**34 (+4)**|139 (+27)|
The most important values here are the total clean build time and the incremental Xcode build time. The first one went down by 369 seconds, the second one went up by 4 seconds. I consider it a reasonable tradeoff.
The extra 4 seconds in the incremental Xcode build time can potentially be mitigated by setting up output file lists for the new script phases.
allow-large-files
Changelog:
[iOS][Changed] - Hermes is integrated into Xcode build.
Reviewed By: hramos
Differential Revision: D40063686
fbshipit-source-id: e6993d62225789377db769244bc07786cc978a27
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35146
This class is used by Fabric - but does not compile on macOS yet.
Changelog:
[iOS][Fixed] Make ManagedObjectWrapper compile on macOS
Reviewed By: javache
Differential Revision: D40839241
fbshipit-source-id: 73b93a9963db89af19529fbfd60a64f4e5aaf036
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35089
Changelog:
[General][Fixed] - Back out "Add enum example to Android/iOS rn-tester TurboModule"
This broke the rn-tester adding due to an invalid flow-enum setup. Needs further investigation
Reviewed By: cipolleschi
Differential Revision: D40714320
fbshipit-source-id: 9831276762f90df0ffaca3304382fe5925009343
Summary:
There are use cases in which we want to pass a set of unique elements from C++ to JS and back. We can do this simple by re-using a plain JS array for these purposes.
Changelog:
[Internal][Added] react-native bridging > Add support for std::set
Reviewed By: cipolleschi
Differential Revision: D40668244
fbshipit-source-id: d06603440569e5f760c2859a54cf6e4232c7d97a
Summary:
Throws a JS error instead of crashing Hermes with an invariant when trying to convert a JS symbol or BigInt to a folly::dynamic value.
Changelog:
[General][Fixed] - Fixed crash when converting JS symbol to folly::dynamic
Reviewed By: javache
Differential Revision: D40444164
fbshipit-source-id: 37df8059b2eb425563f30cf1e9c0436e8d665b34