From 1f6b331854d22cd5018dffbed013cb94637c8d0a Mon Sep 17 00:00:00 2001 From: Radek Pietruszewski Date: Mon, 30 Jan 2023 13:19:43 +0100 Subject: [PATCH 1/2] Run hashing and lipo in parallel --- src/index.ts | 116 +++++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/src/index.ts b/src/index.ts index 34fec69..6239fff 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 + continue; + } + 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`, + ); + 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)), + ]); + }) + ) /** * If we don't have an ASAR we need to check if the two "app" folders are identical, if From 86355de6f65e50636d952f25d1509745077559c2 Mon Sep 17 00:00:00 2001 From: Radek Pietruszewski Date: Mon, 30 Jan 2023 13:28:14 +0100 Subject: [PATCH 2/2] Fix broken loops --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 6239fff..ef1dbfa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -126,7 +126,7 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = // 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; + return; } throw new Error( `Expected all non-binary files to have identical SHAs when creating a universal build but "${file.relativePath}" did not`, @@ -160,7 +160,7 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = machOFile.relativePath, `matches across builds ${x64Sha}===${arm64Sha}, skipping lipo`, ); - continue; + return; } d('joining two MachO files with lipo', {