Skip to content

Commit 7d4ffe2

Browse files
chrfalchclaude
andcommitted
fix(ios-prebuild): carry the execFileSync refactor into headers-xcframework.js
The pure-RN commit moved the stub-xcframework toolchain out of headers-compose.js (which got execFileSync arg arrays on the vfs branch) into this emitter; apply the same conversion here so the shell-quoting fix survives the move: plutil/xcrun/clang/libtool/lipo/xcodebuild/cp all take argument arrays now, with libtool's stderr suppression via stdio options. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 52f008c commit 7d4ffe2

2 files changed

Lines changed: 40 additions & 22 deletions

File tree

packages/react-native/scripts/ios-prebuild/__tests__/headers-xcframework-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ describe('stubSlicesFromXcframework', () => {
6868
// tested without a real xcframework or macOS tooling.
6969
const mockPlist = (obj /*: unknown */) =>
7070
jest
71-
.spyOn(childProcess, 'execSync')
71+
.spyOn(childProcess, 'execFileSync')
7272
.mockReturnValue(Buffer.from(JSON.stringify(obj) ?? '', 'utf8'));
7373

7474
afterEach(() => {

packages/react-native/scripts/ios-prebuild/headers-xcframework.js

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* boundary.
2626
*/
2727

28-
const {execSync} = require('child_process');
28+
const {execFileSync} = require('child_process');
2929
const fs = require('fs');
3030
const path = require('path');
3131

@@ -94,9 +94,13 @@ function stubSlicesFromXcframework(
9494
xcfwPath /*: string */,
9595
) /*: Array<StubSlice> */ {
9696
const plist = JSON.parse(
97-
execSync(
98-
`plutil -convert json -o - "${path.join(xcfwPath, 'Info.plist')}"`,
99-
).toString(),
97+
execFileSync('plutil', [
98+
'-convert',
99+
'json',
100+
'-o',
101+
'-',
102+
path.join(xcfwPath, 'Info.plist'),
103+
]).toString(),
100104
);
101105
return plist.AvailableLibraries.map(lib => {
102106
const key =
@@ -142,37 +146,49 @@ function composeHeadersOnlyXcframework(
142146
`static int ${name}Stub __attribute__((unused)) = 0;\n`,
143147
);
144148
const libs = slices.map(slice => {
145-
const sdkPath = execSync(`xcrun --sdk ${slice.sdk} --show-sdk-path`)
149+
const sdkPath = execFileSync('xcrun', [
150+
'--sdk',
151+
slice.sdk,
152+
'--show-sdk-path',
153+
])
146154
.toString()
147155
.trim();
148156
const thins = slice.targets.map((t, i) => {
149157
const obj = path.join(work, `stub-${slice.name}-${i}.o`);
150-
execSync(
151-
`xcrun clang -c -target ${t} -isysroot "${sdkPath}" "${path.join(work, 'stub.c')}" -o "${obj}"`,
152-
);
158+
execFileSync('xcrun', [
159+
'clang',
160+
'-c',
161+
'-target',
162+
t,
163+
'-isysroot',
164+
sdkPath,
165+
path.join(work, 'stub.c'),
166+
'-o',
167+
obj,
168+
]);
153169
const lib = path.join(work, `stub-${slice.name}-${i}.a`);
154-
execSync(`xcrun libtool -static -o "${lib}" "${obj}" 2>/dev/null`);
170+
execFileSync('xcrun', ['libtool', '-static', '-o', lib, obj], {
171+
stdio: ['ignore', 'pipe', 'ignore'],
172+
});
155173
return lib;
156174
});
157175
const outLib = path.join(work, `lib${name}-${slice.name}.a`);
158176
if (thins.length === 1) {
159177
fs.copyFileSync(thins[0], outLib);
160178
} else {
161-
execSync(
162-
`xcrun lipo -create ${thins.map(l => `"${l}"`).join(' ')} -output "${outLib}"`,
163-
);
179+
execFileSync('xcrun', ['lipo', '-create', ...thins, '-output', outLib]);
164180
}
165181
return outLib;
166182
});
167183

168184
const outXcfw = path.join(outDir, `${name}.xcframework`);
169185
fs.rmSync(outXcfw, {recursive: true, force: true});
170-
execSync(
171-
`xcodebuild -create-xcframework ` +
172-
libs.map(l => `-library "${l}" -headers "${stage}"`).join(' ') +
173-
` -output "${outXcfw}"`,
174-
{stdio: 'pipe'},
175-
);
186+
const xcframeworkArgs = ['-create-xcframework'];
187+
for (const l of libs) {
188+
xcframeworkArgs.push('-library', l, '-headers', stage);
189+
}
190+
xcframeworkArgs.push('-output', outXcfw);
191+
execFileSync('xcodebuild', xcframeworkArgs, {stdio: 'pipe'});
176192
return outXcfw;
177193
} finally {
178194
fs.rmSync(work, {recursive: true, force: true});
@@ -225,9 +241,11 @@ function buildDepsHeadersXcframework(
225241
let outXcfw;
226242
try {
227243
for (const ns of namespaces) {
228-
execSync(
229-
`/bin/cp ${CP_FLAGS} "${path.join(depsHeaders, ns)}" "${path.join(stage, ns)}"`,
230-
);
244+
execFileSync('/bin/cp', [
245+
CP_FLAGS,
246+
path.join(depsHeaders, ns),
247+
path.join(stage, ns),
248+
]);
231249
}
232250
outXcfw = composeHeadersOnlyXcframework(
233251
outDir,

0 commit comments

Comments
 (0)