electron / universal

Create Universal macOS applications from two x64 and arm64 Electron applications
MIT License
112 stars 43 forks source link

Merged ASAR does not unpack correctly when there is only one unpacked file #54

Closed quanglam2807 closed 1 year ago

quanglam2807 commented 1 year ago

Currently, we are using electron-builder@23.5.1 which is using @electron/universal. Recent versions of electron-builder enable mergeASARs which cause issues with native dependencies: @electron/universal does not contruct app.asar.unpacked correctly after processing.

Details

To support native dependencies (e.g. better-sqlite3), we unpack the executable binaries from app.asar, thus we have a structure like this for each package (arm64 and x64).

app.asar
app.asar.unpacked
   node_modules
      better-sqlite3
         build
            Release
               better-sqlite3.node

@electron/universal will then run lipo to merge better-sqlite3.node in arm64 and x64 together to generate universal better-sqlite3.node . This step works correctly. https://github.com/electron/universal/blob/3a30fe989bee57d93b3da7beb9e9bf8ca29639fc/src/asar-utils.ts#L186

Nevertheless, when it generates the ASAR file with universal bindings,

await asar.createPackageWithOptions(x64Dir, outputAsarPath, {
  unpack: `{${resolvedUnpack.join(',')}}`,
});

The unpack value is incorrect as asar does not unpack any files. app.asar.unpacked remains the pre-processed directory of x64.

After debugging, this is what I've found:

=> minimatch(filename, options.unpack, { matchBase: true }) (https://github.com/electron/asar/blob/db6d1541be05f67933f07c6f30d2425a05f13182/lib/asar.js#L123) returns false, causing the file not to be unpacked.

Debugging Logs

Binding in tmp destination (used during ASAR merging process) => universal

file /var/folders/9q/565lwvz54k7529bzvbyqpz040000gn/T/x64-0QZm6y/node_modules/better-sqlite3/build/Release/better_sqlite3.node
/var/folders/9q/565lwvz54k7529bzvbyqpz040000gn/T/x64-0QZm6y/node_modules/better-sqlite3/build/Release/better_sqlite3.node: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit bundle x86_64] [arm64]
/var/folders/9q/565lwvz54k7529bzvbyqpz040000gn/T/x64-0QZm6y/node_modules/better-sqlite3/build/Release/better_sqlite3.node (for architecture x86_64):    Mach-O 64-bit bundle x86_64
/var/folders/9q/565lwvz54k7529bzvbyqpz040000gn/T/x64-0QZm6y/node_modules/better-sqlite3/build/Release/better_sqlite3.node (for architecture arm64): Mach-O 64-bit bundle arm64

Binding in final destination => x64 only

file dist/mac-universal/Singlebox.app/Contents/Resources/app.asar.unpacked/node_modules/better-sqlite3/build/Release/better_sqlite3.node
dist/mac-universal/Singlebox.app/Contents/Resources/app.asar.unpacked/node_modules/better-sqlite3/build/Release/better_sqlite3.node: Mach-O 64-bit bundle x86_64

minimatch output false

minimatch('/var/folders/9q/565lwvz54k7529bzvbyqpz040000gn/T/x64-0QZm6y/node_modules/better-sqlite3/build/Release/better_sqlite3.node', '{/var/folders/9q/565lwvz54k7529bzvbyqpz040000gn/T/x64-0QZm6y/node_modules/better-sqlite3/build/Release/better_sqlite3.node}', { matchBase: true });

@mmaietta

continuous-auth[bot] commented 1 year ago

:tada: This issue has been resolved in version 1.3.3 :tada:

The release is available on:

Your semantic-release bot :package::rocket: