diff --git a/src/index.ts b/src/index.ts index 34fec69..ef1dbfa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -114,60 +114,68 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = 'While trying to merge mach-o files across your apps we found a mismatch, the number of mach-o files is not the same between the arm64 and x64 builds', ); } - - for (const file of x64Files.filter((f) => f.type === AppFileType.PLAIN)) { - const x64Sha = await sha(path.resolve(opts.x64AppPath, file.relativePath)); - const arm64Sha = await sha(path.resolve(opts.arm64AppPath, file.relativePath)); - if (x64Sha !== arm64Sha) { - d('SHA for file', file.relativePath, `does not match across builds ${x64Sha}!=${arm64Sha}`); - // The MainMenu.nib files generated by Xcode13 are deterministic in effect but not deterministic in generated sequence - if (path.basename(path.dirname(file.relativePath)) === 'MainMenu.nib') { - // The mismatch here is OK so we just move on to the next one - continue; - } - throw new Error( - `Expected all non-binary files to have identical SHAs when creating a universal build but "${file.relativePath}" did not`, - ); - } - } - - for (const machOFile of x64Files.filter((f) => f.type === AppFileType.MACHO)) { - const first = await fs.realpath(path.resolve(tmpApp, machOFile.relativePath)); - const second = await fs.realpath(path.resolve(opts.arm64AppPath, machOFile.relativePath)); - - const x64Sha = await sha(path.resolve(opts.x64AppPath, machOFile.relativePath)); - const arm64Sha = await sha(path.resolve(opts.arm64AppPath, machOFile.relativePath)); - if (x64Sha === arm64Sha) { - if ( - opts.x64ArchFiles === undefined || - !minimatch(machOFile.relativePath, opts.x64ArchFiles, { matchBase: true }) - ) { - throw new Error( - `Detected file "${machOFile.relativePath}" that's the same in both x64 and arm64 builds and not covered by the ` + - `x64ArchFiles rule: "${opts.x64ArchFiles}"`, - ); - } - - d( - 'SHA for Mach-O file', - machOFile.relativePath, - `matches across builds ${x64Sha}===${arm64Sha}, skipping lipo`, - ); - continue; - } - - d('joining two MachO files with lipo', { - first, - second, - }); - await spawn('lipo', [ - first, - second, - '-create', - '-output', - await fs.realpath(path.resolve(tmpApp, machOFile.relativePath)), - ]); - } + + await Promise.all( + x64Files + .filter((f) => f.type === AppFileType.PLAIN) + .map(async (file) => { + const x64Sha = await sha(path.resolve(opts.x64AppPath, file.relativePath)); + const arm64Sha = await sha(path.resolve(opts.arm64AppPath, file.relativePath)); + if (x64Sha !== arm64Sha) { + d('SHA for file', file.relativePath, `does not match across builds ${x64Sha}!=${arm64Sha}`); + // The MainMenu.nib files generated by Xcode13 are deterministic in effect but not deterministic in generated sequence + if (path.basename(path.dirname(file.relativePath)) === 'MainMenu.nib') { + // The mismatch here is OK so we just move on to the next one + return; + } + throw new Error( + `Expected all non-binary files to have identical SHAs when creating a universal build but "${file.relativePath}" did not`, + ); + } + }) + ) + + await Promise.all( + x64Files + .filter((f) => f.type === AppFileType.MACHO) + .map(async (machOFile) => { + const first = await fs.realpath(path.resolve(tmpApp, machOFile.relativePath)); + const second = await fs.realpath(path.resolve(opts.arm64AppPath, machOFile.relativePath)); + + const x64Sha = await sha(path.resolve(opts.x64AppPath, machOFile.relativePath)); + const arm64Sha = await sha(path.resolve(opts.arm64AppPath, machOFile.relativePath)); + if (x64Sha === arm64Sha) { + if ( + opts.x64ArchFiles === undefined || + !minimatch(machOFile.relativePath, opts.x64ArchFiles, { matchBase: true }) + ) { + throw new Error( + `Detected file "${machOFile.relativePath}" that's the same in both x64 and arm64 builds and not covered by the ` + + `x64ArchFiles rule: "${opts.x64ArchFiles}"`, + ); + } + + d( + 'SHA for Mach-O file', + machOFile.relativePath, + `matches across builds ${x64Sha}===${arm64Sha}, skipping lipo`, + ); + return; + } + + d('joining two MachO files with lipo', { + first, + second, + }); + await spawn('lipo', [ + first, + second, + '-create', + '-output', + await fs.realpath(path.resolve(tmpApp, machOFile.relativePath)), + ]); + }) + ) /** * If we don't have an ASAR we need to check if the two "app" folders are identical, if