Skip to content

Commit

Permalink
feat: don't lipo binaries that are identical in the x64 and arm64 ver…
Browse files Browse the repository at this point in the history
…sions and match an allowlist (#47)

* fix: Don’t lipo binaries that are already a universal file or the same arch #17

Some Mach-O files may have already been fat binaries and will throw an error if lipoed again.

Co-authored-by: Mitch Cohen <[email protected]>
Co-authored-by: Nick McGuire <[email protected]>

* Add a x64ArchFiles config key to allow allow-listing of files that are only always x64Arch

Co-authored-by: Andrew Beyer <[email protected]>
Co-authored-by: Mitch Cohen <[email protected]>
Co-authored-by: Nick McGuire <[email protected]>
  • Loading branch information
4 people committed Jun 1, 2022
1 parent 3bd173d commit 01dfb8a
Showing 1 changed file with 26 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { spawn } from '@malept/cross-spawn-promise';
import * as asar from 'asar';
import * as crypto from 'crypto';
import * as fs from 'fs-extra';
import * as minimatch from 'minimatch';
import * as os from 'os';
import * as path from 'path';
import * as plist from 'plist';
Expand Down Expand Up @@ -39,6 +40,10 @@ type MakeUniversalOpts = {
* Minimatch pattern of paths that are allowed to be present in one of the ASAR files, but not in the other.
*/
singleArchFiles?: string;
/**
* Minimatch pattern of binaries that are expected to be the same x64 binary in both of the ASAR files.
*/
x64ArchFiles?: string;
};

const dupedFiles = (files: AppFile[]) =>
Expand Down Expand Up @@ -130,6 +135,27 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise<void> =
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,
Expand Down

0 comments on commit 01dfb8a

Please sign in to comment.