feat: don't lipo binaries that are identical in the x64 and arm64 versions 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 <mitch@1password.com> Co-authored-by: Nick McGuire <nick.mcguire@1password.com> * Add a x64ArchFiles config key to allow allow-listing of files that are only always x64Arch Co-authored-by: Andrew Beyer <beyer@1password.com> Co-authored-by: Mitch Cohen <mitch@1password.com> Co-authored-by: Nick McGuire <nick.mcguire@1password.com>
This commit is contained in:
26
src/index.ts
26
src/index.ts
@@ -2,6 +2,7 @@ import { spawn } from '@malept/cross-spawn-promise';
|
|||||||
import * as asar from 'asar';
|
import * as asar from 'asar';
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
|
import * as minimatch from 'minimatch';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as plist from 'plist';
|
import * as plist from 'plist';
|
||||||
@@ -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.
|
* Minimatch pattern of paths that are allowed to be present in one of the ASAR files, but not in the other.
|
||||||
*/
|
*/
|
||||||
singleArchFiles?: string;
|
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[]) =>
|
const dupedFiles = (files: AppFile[]) =>
|
||||||
@@ -130,6 +135,27 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise<void> =
|
|||||||
const first = await fs.realpath(path.resolve(tmpApp, machOFile.relativePath));
|
const first = await fs.realpath(path.resolve(tmpApp, machOFile.relativePath));
|
||||||
const second = await fs.realpath(path.resolve(opts.arm64AppPath, 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', {
|
d('joining two MachO files with lipo', {
|
||||||
first,
|
first,
|
||||||
second,
|
second,
|
||||||
|
|||||||
Reference in New Issue
Block a user