Skip to content

Commit b7e046e

Browse files
chrfalchfacebook-github-bot
authored andcommitted
change header structure rn deps in XCFrameworks (facebook#50085)
Summary: Headers are currently copied into each arch in the final xcframework. This is not necessary and will cause a lot of duplication since these files are the same for all archs. This commit fixes this by only copying headers when we build the final XCFramework: - ReactNativeDependencies.podspec: Changed the prepare script to be more resilient to different header structs, since we have multiple ways of packaging our tarballs locally and on the servers - build.js: Removed copying headers when building frameworks - compose-framework.js: Added copying headers once to the root of the XCFramework. - rndependencies.rb: updated docs with correct ENV vars bypass-github-export-checks ## Changelog: [INTERNAL] - Changes the header structure in our XCFramework to avoid duplication Pull Request resolved: facebook#50085 Test Plan: Run RNTester with RCT_USE_RN_DEPS=1 to use prebuilt RN Deps. Reviewed By: javache Differential Revision: D71385183 Pulled By: cipolleschi fbshipit-source-id: 160d56dea7f61d1b8d0a45b80f6c0789647358e6
1 parent 9cf1383 commit b7e046e

File tree

5 files changed

+52
-85
lines changed

5 files changed

+52
-85
lines changed

.github/workflows/prebuild-ios.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ jobs:
143143
- name: Yarn Install
144144
if: steps.restore-xcframework.outputs.cache-hit != 'true'
145145
uses: ./.github/actions/yarn-install
146+
- name: Restore workspace
147+
if: steps.restore-xcframework.outputs.cache-hit != 'true'
148+
uses: actions/download-artifact@v4
149+
with:
150+
name: ios-prebuilds-workspace
151+
path: packages/react-native/third-party/
146152
- name: Download slices
147153
if: steps.restore-xcframework.outputs.cache-hit != 'true'
148154
uses: actions/download-artifact@v4

packages/react-native/scripts/cocoapods/rndependencies.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
## There are two environment variables that is related to ReactNativeDependencies:
1313
## - RCT_USE_RN_DEP: If set to 1, it will use the release tarball from Maven instead of building from source.
14+
## - RCT_USE_LOCAL_RN_DEP: **TEST ONLY** If set, it will use a local tarball of ReactNativeDependencies if it exists.
1415
## - RCT_DEPS_VERSION: **TEST ONLY** If set, it will override the version of ReactNativeDependencies to be used.
1516

1617
### Adds ReactNativeDependencies as a dependency to the given podspec if we're not

packages/react-native/third-party-podspecs/ReactNativeDependencies.podspec

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,17 @@ Pod::Spec.new do |spec|
4141
spec.vendored_frameworks = 'framework/packages/react-native/ReactNativeDependencies.xcframework'
4242
spec.header_mappings_dir = 'Headers'
4343
spec.source_files = 'Headers/**/*.{h,hpp}'
44+
45+
# We need to make sure that the headers are copied to the right place - local tar.gz has a different structure
46+
# than the one from the maven repo
4447
spec.prepare_command = <<-CMD
45-
pwd
4648
CURRENT_PATH=$(pwd)
4749
mkdir -p Headers
48-
BASE_PATH=$(find "$CURRENT_PATH" -type d -name "ios-arm64")
49-
rsync -a "$BASE_PATH/ReactNativeDependencies.framework/Headers/" Headers
50+
XCFRAMEWORK_PATH=$(find "$CURRENT_PATH" -type d -name "ReactNativeDependencies.xcframework")
51+
HEADERS_PATH=$(find "$XCFRAMEWORK_PATH" -type d -name "Headers" | head -n 1)
52+
rsync -a "$HEADERS_PATH/" Headers
5053
mkdir -p framework/packages/react-native
51-
rsync -a --remove-source-files "$BASE_PATH/../.." framework/packages/react-native/
54+
rsync -a --remove-source-files "$XCFRAMEWORK_PATH/.." framework/packages/react-native/
5255
find "$CURRENT_PATH" -type d -empty -delete
5356
CMD
5457

scripts/releases/ios-prebuild/build.js

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@
99
* @oncall react_native
1010
*/
1111

12-
const {HEADERS_FOLDER, TARGET_FOLDER} = require('./constants');
13-
const {getAllFilesRecursively} = require('./folders');
1412
const {execSync} = require('child_process');
15-
const fs = require('fs');
16-
const path = require('path');
1713

1814
/*::
1915
import type { Dependency, Destination, Platform } from './types';
@@ -45,9 +41,6 @@ async function buildDepenencies(
4541
),
4642
),
4743
);
48-
49-
// Copy headers into framework
50-
await copyHeadersToFrameworks(scheme, dependencies, rootFolder, buildFolder);
5144
}
5245

5346
/**
@@ -72,79 +65,6 @@ async function buildPlatform(
7265
execSync(command, {cwd: rootFolder, stdio: 'inherit'});
7366
}
7467

75-
/**
76-
* Copies headers needed from the package to the framework
77-
*/
78-
async function copyHeadersToFrameworks(
79-
scheme /*: string */,
80-
dependencies /*: $ReadOnlyArray<Dependency> */,
81-
rootFolder /*: string */,
82-
buildFolder /*: string */,
83-
) {
84-
const frameworkFolder = path.join(buildFolder, 'Build', 'Products');
85-
const frameworks = fs
86-
.readdirSync(frameworkFolder)
87-
.filter(f => fs.statSync(path.join(frameworkFolder, f)).isDirectory());
88-
89-
console.log('Frameworks found:', frameworks.join(', '));
90-
const frameworkPaths = frameworks.map(framework =>
91-
path.join(frameworkFolder, framework),
92-
);
93-
94-
// Create Header folder
95-
frameworkPaths.forEach(fp => {
96-
const headerFolder = path.join(
97-
fp,
98-
'PackageFrameworks',
99-
`${scheme}.framework`,
100-
'Headers',
101-
);
102-
// Delete and recreate the folder
103-
fs.rmSync(headerFolder, {force: true, recursive: true});
104-
fs.mkdirSync(headerFolder, {recursive: true});
105-
});
106-
107-
// Now we can go through all dependencies and copy header files for each depencendy
108-
dependencies.forEach(dep => {
109-
const depHeadersFolder = path.join(
110-
rootFolder,
111-
dep.name,
112-
TARGET_FOLDER,
113-
HEADERS_FOLDER,
114-
);
115-
const publicHeaderFiles = path.join(depHeadersFolder);
116-
117-
// Get files in public header files
118-
const headerFiles = getAllFilesRecursively(publicHeaderFiles);
119-
console.log(
120-
`Copying ${headerFiles.length} headers from "${dep.name}" to framework.`,
121-
);
122-
123-
// Copy files into headers in framework
124-
headerFiles.map(p => {
125-
frameworkPaths.forEach(fp => {
126-
const destination = path.join(
127-
fp,
128-
'PackageFrameworks',
129-
`${scheme}.framework`,
130-
'Headers',
131-
p.replace(publicHeaderFiles, ''),
132-
);
133-
134-
// Create folder if it doesn't exist
135-
if (!fs.existsSync(path.dirname(destination))) {
136-
fs.mkdirSync(path.dirname(destination), {
137-
force: true,
138-
recursive: true,
139-
});
140-
}
141-
// Copy
142-
fs.copyFileSync(p, destination);
143-
});
144-
});
145-
});
146-
}
147-
14868
module.exports = {
14969
buildDepenencies,
15070
};

scripts/releases/ios-prebuild/compose-framework.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
* @oncall react_native
1010
*/
1111

12+
const {HEADERS_FOLDER, TARGET_FOLDER} = require('./constants');
1213
const {execSync} = require('child_process');
1314
const fs = require('fs');
1415
const path = require('path');
1516

1617
/*::
1718
import type { Dependency, Platform } from './types';
18-
import {exec} from "child_process";
1919
*/
2020

2121
/**
@@ -64,6 +64,9 @@ async function createFramework(
6464
// Copy bundles into the framework
6565
copyBundles(scheme, dependencies, output, frameworkPaths);
6666

67+
// Copy headers to the framework - start by building the Header folder
68+
await copyHeaders(scheme, dependencies, rootFolder);
69+
6770
// Copy Symbols to symbols folder
6871
const symbolPaths = frameworkPaths.map(framework =>
6972
path.join(framework, `${scheme}.framework.dSYM`),
@@ -78,6 +81,40 @@ async function createFramework(
7881
}
7982
}
8083

84+
/**
85+
* Copies headers needed from the package to a Header folder that we'll pass to
86+
* each framework arch type
87+
*/
88+
async function copyHeaders(
89+
scheme /*: string */,
90+
dependencies /*: $ReadOnlyArray<Dependency> */,
91+
rootFolder /*: string */,
92+
) {
93+
console.log('Copying header files for dependencies...');
94+
95+
// Create and clean the header folder
96+
const headeDestinationFolder = path.join(
97+
rootFolder,
98+
`${scheme}.xcframework`,
99+
'Headers',
100+
);
101+
fs.rmSync(headeDestinationFolder, {force: true, recursive: true});
102+
fs.mkdirSync(headeDestinationFolder, {recursive: true});
103+
104+
// Now we can go through all dependencies and copy header files for each depencendy
105+
dependencies.forEach(dep => {
106+
const depHeaders = path.join(
107+
rootFolder,
108+
dep.name,
109+
TARGET_FOLDER,
110+
HEADERS_FOLDER,
111+
);
112+
113+
// Copy all header files from the dependency to headerTempFolder
114+
execSync(`cp -r ${depHeaders}/* ${headeDestinationFolder}/`);
115+
});
116+
}
117+
81118
/**
82119
* Copies the bundles in the source frameworks to the target xcframework inside the xcframework's Resources folder
83120
*/

0 commit comments

Comments
 (0)