Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c01deb5576 | ||
|
|
82acb6fc72 | ||
|
|
8bb61593b2 | ||
|
|
3ebf924651 | ||
|
|
46a3b7e94d |
@@ -30,3 +30,7 @@ because it contains two apps in one.
|
|||||||
The way `@electron/universal` works today means you don't need to worry about
|
The way `@electron/universal` works today means you don't need to worry about
|
||||||
things like building universal versions of your native modules. As long as
|
things like building universal versions of your native modules. As long as
|
||||||
your x64 and arm64 apps work in isolation the Universal app will work as well.
|
your x64 and arm64 apps work in isolation the Universal app will work as well.
|
||||||
|
|
||||||
|
#### How do I build my app for Apple silicon in the first place?
|
||||||
|
|
||||||
|
Check out the [Electron Apple silicon blog post](https://www.electronjs.org/blog/apple-silicon)
|
||||||
7
entry-asar/has-asar.js
Normal file
7
entry-asar/has-asar.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
if (process.arch === 'arm64') {
|
||||||
|
process._archPath = require.resolve('../app-arm64.asar');
|
||||||
|
} else {
|
||||||
|
process._archPath = require.resolve('../app-x64.asar');
|
||||||
|
}
|
||||||
|
|
||||||
|
require(process._archPath);
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
if (process.arch === 'arm64') {
|
|
||||||
process._asarPath = require.resolve('../arm64.app.asar');
|
|
||||||
} else {
|
|
||||||
process._asarPath = require.resolve('../x64.app.asar');
|
|
||||||
}
|
|
||||||
|
|
||||||
require(process._asarPath);
|
|
||||||
7
entry-asar/no-asar.js
Normal file
7
entry-asar/no-asar.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
if (process.arch === 'arm64') {
|
||||||
|
process._archPath = require.resolve('../app-arm64');
|
||||||
|
} else {
|
||||||
|
process._archPath = require.resolve('../app-x64');
|
||||||
|
}
|
||||||
|
|
||||||
|
require(process._archPath);
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist/*",
|
"dist/*",
|
||||||
|
"entry-asar/*",
|
||||||
"README.md"
|
"README.md"
|
||||||
],
|
],
|
||||||
"author": "Samuel Attard",
|
"author": "Samuel Attard",
|
||||||
@@ -37,6 +38,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@malept/cross-spawn-promise": "^1.1.0",
|
"@malept/cross-spawn-promise": "^1.1.0",
|
||||||
"asar": "^3.0.3",
|
"asar": "^3.0.3",
|
||||||
|
"dir-compare": "^2.4.0",
|
||||||
"fs-extra": "^9.0.1"
|
"fs-extra": "^9.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
61
src/index.ts
61
src/index.ts
@@ -4,6 +4,7 @@ import * as crypto from 'crypto';
|
|||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import * as dircompare from 'dir-compare';
|
||||||
|
|
||||||
const MACHO_PREFIX = 'Mach-O ';
|
const MACHO_PREFIX = 'Mach-O ';
|
||||||
|
|
||||||
@@ -174,34 +175,48 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise<void> =
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (x64AsarMode === AsarMode.NO_ASAR) {
|
if (x64AsarMode === AsarMode.NO_ASAR) {
|
||||||
await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'x64.app'));
|
const comparison = dircompare.compareSync(path.resolve(tmpApp, 'Contents', 'Resources', 'app'), path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app'), { compareSize: true, compareContent: true });
|
||||||
await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'arm64.app'));
|
|
||||||
} else {
|
|
||||||
await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'), path.resolve(tmpApp, 'Contents', 'Resources', 'x64.app.asar'));
|
|
||||||
const x64Unpacked = path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar.unpacked');
|
|
||||||
if (await fs.pathExists(x64Unpacked)) {
|
|
||||||
await fs.move(x64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'x64.app.asar.unpacked'));
|
|
||||||
}
|
|
||||||
|
|
||||||
await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar'), path.resolve(tmpApp, 'Contents', 'Resources', 'arm64.app.asar'));
|
if (!comparison.same) {
|
||||||
const arm64Unpacked = path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar.unpacked');
|
await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-x64'));
|
||||||
if (await fs.pathExists(arm64Unpacked)) {
|
await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-arm64'));
|
||||||
await fs.copy(arm64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'arm64.app.asar.unpacked'));
|
|
||||||
|
const entryAsar = path.resolve(tmpDir, 'entry-asar');
|
||||||
|
await fs.mkdir(entryAsar);
|
||||||
|
await fs.copy(path.resolve(__dirname, '..', '..', 'entry-asar', 'no-asar.js'), path.resolve(entryAsar, 'index.js'));
|
||||||
|
let pj = await fs.readJson(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app', 'package.json'));
|
||||||
|
pj.main = 'index.js';
|
||||||
|
await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj);
|
||||||
|
await asar.createPackage(entryAsar, path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const entryAsar = path.resolve(tmpDir, 'entry-asar');
|
if (x64AsarMode === AsarMode.HAS_ASAR) {
|
||||||
await fs.mkdir(entryAsar);
|
const x64AsarSha = await sha(path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'));
|
||||||
await fs.copy(path.resolve(__dirname, '..', '..', 'entry-asar', 'index.js'), path.resolve(entryAsar, 'index.js'));
|
const arm64AsarSha = await sha(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar'));
|
||||||
let pj: any;
|
|
||||||
if (x64AsarMode === AsarMode.NO_ASAR) {
|
if (x64AsarSha !== arm64AsarSha) {
|
||||||
pj = await fs.readJson(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app', 'package.json'));
|
await fs.move(path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-x64.asar'));
|
||||||
} else {
|
const x64Unpacked = path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar.unpacked');
|
||||||
pj = JSON.parse((await asar.extractFile(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app.asar'), 'package.json')).toString('utf8'));
|
if (await fs.pathExists(x64Unpacked)) {
|
||||||
|
await fs.move(x64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'app-x64.asar.unpacked'));
|
||||||
|
}
|
||||||
|
|
||||||
|
await fs.copy(path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar'), path.resolve(tmpApp, 'Contents', 'Resources', 'app-arm64.asar'));
|
||||||
|
const arm64Unpacked = path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar.unpacked');
|
||||||
|
if (await fs.pathExists(arm64Unpacked)) {
|
||||||
|
await fs.copy(arm64Unpacked, path.resolve(tmpApp, 'Contents', 'Resources', 'app-arm64.asar.unpacked'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const entryAsar = path.resolve(tmpDir, 'entry-asar');
|
||||||
|
await fs.mkdir(entryAsar);
|
||||||
|
await fs.copy(path.resolve(__dirname, '..', '..', 'entry-asar', 'has-asar.js'), path.resolve(entryAsar, 'index.js'));
|
||||||
|
let pj = JSON.parse((await asar.extractFile(path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app.asar'), 'package.json')).toString('utf8'));
|
||||||
|
pj.main = 'index.js';
|
||||||
|
await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj);
|
||||||
|
await asar.createPackage(entryAsar, path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pj.main = 'index.js';
|
|
||||||
await fs.writeJson(path.resolve(entryAsar, 'package.json'), pj);
|
|
||||||
await asar.createPackage(entryAsar, path.resolve(tmpApp, 'Contents', 'Resources', 'app.asar'));
|
|
||||||
|
|
||||||
for (const snapshotsFile of arm64Files.filter(f => f.type === AppFileType.SNAPSHOT)) {
|
for (const snapshotsFile of arm64Files.filter(f => f.type === AppFileType.SNAPSHOT)) {
|
||||||
await fs.copy(path.resolve(opts.arm64AppPath, snapshotsFile.relativePath), path.resolve(tmpApp, snapshotsFile.relativePath));
|
await fs.copy(path.resolve(opts.arm64AppPath, snapshotsFile.relativePath), path.resolve(tmpApp, snapshotsFile.relativePath));
|
||||||
|
|||||||
35
yarn.lock
35
yarn.lock
@@ -616,6 +616,11 @@ braces@^3.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
fill-range "^7.0.1"
|
fill-range "^7.0.1"
|
||||||
|
|
||||||
|
buffer-equal@1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe"
|
||||||
|
integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74=
|
||||||
|
|
||||||
buffer-from@^1.0.0:
|
buffer-from@^1.0.0:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||||
@@ -900,6 +905,13 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
|
|||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream "~1.0.0"
|
delayed-stream "~1.0.0"
|
||||||
|
|
||||||
|
commander@2.9.0:
|
||||||
|
version "2.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
|
||||||
|
integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=
|
||||||
|
dependencies:
|
||||||
|
graceful-readlink ">= 1.0.0"
|
||||||
|
|
||||||
commander@^5.0.0:
|
commander@^5.0.0:
|
||||||
version "5.1.0"
|
version "5.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
|
||||||
@@ -1211,6 +1223,16 @@ dezalgo@^1.0.0, dezalgo@~1.0.3:
|
|||||||
asap "^2.0.0"
|
asap "^2.0.0"
|
||||||
wrappy "1"
|
wrappy "1"
|
||||||
|
|
||||||
|
dir-compare@^2.4.0:
|
||||||
|
version "2.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-2.4.0.tgz#785c41dc5f645b34343a4eafc50b79bac7f11631"
|
||||||
|
integrity sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA==
|
||||||
|
dependencies:
|
||||||
|
buffer-equal "1.0.0"
|
||||||
|
colors "1.0.3"
|
||||||
|
commander "2.9.0"
|
||||||
|
minimatch "3.0.4"
|
||||||
|
|
||||||
dir-glob@^3.0.0, dir-glob@^3.0.1:
|
dir-glob@^3.0.0, dir-glob@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
||||||
@@ -1804,6 +1826,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
|
|||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||||
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
||||||
|
|
||||||
|
"graceful-readlink@>= 1.0.0":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
|
||||||
|
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
|
||||||
|
|
||||||
handlebars@^4.7.6:
|
handlebars@^4.7.6:
|
||||||
version "4.7.6"
|
version "4.7.6"
|
||||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e"
|
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e"
|
||||||
@@ -2864,7 +2891,7 @@ min-indent@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
|
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
|
||||||
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
|
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
|
||||||
|
|
||||||
minimatch@^3.0.4:
|
minimatch@3.0.4, minimatch@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||||
@@ -4103,9 +4130,9 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
|||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||||
|
|
||||||
semantic-release@^17.2.2:
|
semantic-release@^17.2.2:
|
||||||
version "17.2.2"
|
version "17.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-17.2.2.tgz#520dae9cd188c7cdcc5216a7aad131548fc5cec7"
|
resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-17.2.3.tgz#11f10b851d4e75b1015b17515c433049b3df994c"
|
||||||
integrity sha512-LNU68ud3a3oU46H11OThXaKAK430jGGGTIF4VsiP843kRmS6s8kVCceLRdi7yWWz/sCCMD0zygPTQV2Jw79J5g==
|
integrity sha512-MY1MlowGQrkOR7+leOD8ICkVOC6i1szbwDODdbJ0UdshtMx8Ms0bhpRQmEEliqYKEb5PLv/dqs6zKKuHT7UxTg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@semantic-release/commit-analyzer" "^8.0.0"
|
"@semantic-release/commit-analyzer" "^8.0.0"
|
||||||
"@semantic-release/error" "^2.2.0"
|
"@semantic-release/error" "^2.2.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user