Skip to content

Commit f8f5eb2

Browse files
chrfalchclaude
andcommitted
fix(ios-prebuild): execFileSync arg arrays for the stub-xcframework toolchain calls
The xcrun/clang/libtool/lipo/xcodebuild invocations in buildReactNativeHeadersXcframework used execSync with template-interpolated double-quoted paths; a path containing a quote or dollar sign could break or shell-expand. Converted to execFileSync argument arrays (matching headers-verify.js and the existing cp calls); libtool's 2>/dev/null shell redirect becomes stdio: ['ignore', 'pipe', 'ignore']. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 052b7f9 commit f8f5eb2

1 file changed

Lines changed: 27 additions & 15 deletions

File tree

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

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const {
2626
renderReactModuleMap,
2727
renderUmbrellaHeader,
2828
} = require('./headers-spec');
29-
const {execFileSync, execSync} = require('child_process');
29+
const {execFileSync} = require('child_process');
3030
const crypto = require('crypto');
3131
const fs = require('fs');
3232
const path = require('path');
@@ -287,38 +287,50 @@ function buildReactNativeHeadersXcframework(
287287
? [...DEFAULT_STUB_SLICES, CATALYST_STUB_SLICE]
288288
: DEFAULT_STUB_SLICES;
289289
const libs = slices.map(slice => {
290-
const sdkPath = execSync(`xcrun --sdk ${slice.sdk} --show-sdk-path`)
290+
const sdkPath = execFileSync('xcrun', [
291+
'--sdk',
292+
slice.sdk,
293+
'--show-sdk-path',
294+
])
291295
.toString()
292296
.trim();
293297
const thins = slice.targets.map((t, i) => {
294298
const obj = path.join(work, `stub-${slice.name}-${i}.o`);
295-
execSync(
296-
`xcrun clang -c -target ${t} -isysroot "${sdkPath}" "${path.join(work, 'stub.c')}" -o "${obj}"`,
297-
);
299+
execFileSync('xcrun', [
300+
'clang',
301+
'-c',
302+
'-target',
303+
t,
304+
'-isysroot',
305+
sdkPath,
306+
path.join(work, 'stub.c'),
307+
'-o',
308+
obj,
309+
]);
298310
const lib = path.join(work, `stub-${slice.name}-${i}.a`);
299-
execSync(`xcrun libtool -static -o "${lib}" "${obj}" 2>/dev/null`);
311+
execFileSync('xcrun', ['libtool', '-static', '-o', lib, obj], {
312+
stdio: ['ignore', 'pipe', 'ignore'],
313+
});
300314
return lib;
301315
});
302316
const outLib = path.join(work, `libReactNativeHeaders-${slice.name}.a`);
303317
if (thins.length === 1) {
304318
fs.copyFileSync(thins[0], outLib);
305319
} else {
306-
execSync(
307-
`xcrun lipo -create ${thins.map(l => `"${l}"`).join(' ')} -output "${outLib}"`,
308-
);
320+
execFileSync('xcrun', ['lipo', '-create', ...thins, '-output', outLib]);
309321
}
310322
return outLib;
311323
});
312324

313325
// ---- compose ----
314326
const outXcfw = path.join(outDir, 'ReactNativeHeaders.xcframework');
315327
fs.rmSync(outXcfw, {recursive: true, force: true});
316-
execSync(
317-
`xcodebuild -create-xcframework ` +
318-
libs.map(l => `-library "${l}" -headers "${stage}"`).join(' ') +
319-
` -output "${outXcfw}"`,
320-
{stdio: 'pipe'},
321-
);
328+
const xcframeworkArgs = ['-create-xcframework'];
329+
for (const l of libs) {
330+
xcframeworkArgs.push('-library', l, '-headers', stage);
331+
}
332+
xcframeworkArgs.push('-output', outXcfw);
333+
execFileSync('xcodebuild', xcframeworkArgs, {stdio: 'pipe'});
322334
fs.rmSync(stage, {recursive: true, force: true});
323335
fs.rmSync(work, {recursive: true, force: true});
324336
console.log(

0 commit comments

Comments
 (0)