Electron-builder: Apple Silicon arm64 support

Created on 6 Nov 2020  Â·  25Comments  Â·  Source: electron-userland/electron-builder


  • 22.9.1:


  • Eelectron 11:
  • Electron Type (current, beta, nightly):
    beta

  • macOS:


With the release of Electron 11.0.0-beta.1, the Electron team is now shipping builds of Electron that run on the new Apple Silicon hardware
more info about Apple Silicon Support https://www.electronjs.org/blog/apple-silicon

Most helpful comment

I've built a pkg file with arm64 binary and x64 binary, uploaded it to apple for review, and unfortunately the latest version of electron beta contains some private api calls that cause my app to be rejected. here's the details https://github.com/electron/electron/issues/26480

Anyway, here's how I built it.
1 Build the x64 version of the app normally first.
2 Using electron-rebuild -f --arch=arm64 to build native modules for arm64 architecture
3 Configure electron-builder's electronDownload.arch value to "arm64"
4 Run electron-builder to build the arm64 version of the app.
5 Merge x64 and arm64 versions using @electron/universal
6 Manually signing the merged univeral app

All 25 comments

  • 22.9.1:

  • Eelectron 11:

  • Electron Type (current, beta, nightly):
    beta

  • macOS:

With the release of Electron 11.0.0-beta.1, the Electron team is now shipping builds of Electron that run on the new Apple Silicon hardware
more info about Apple Silicon Support https://www.electronjs.org/blog/apple-silicon

@gaodeng but electron-builder is not supporting ARM64.

Please support ARM64!!!! Don't want to have to move to another package!

Apple will release to his customers three different models of ARM64 macs in 6 days, the support for this is planned/in progress?

Currently stressing/investigating into this. I love electron-builder and would prefer not to switch.

I've built a pkg file with arm64 binary and x64 binary, uploaded it to apple for review, and unfortunately the latest version of electron beta contains some private api calls that cause my app to be rejected. here's the details https://github.com/electron/electron/issues/26480

Anyway, here's how I built it.
1 Build the x64 version of the app normally first.
2 Using electron-rebuild -f --arch=arm64 to build native modules for arm64 architecture
3 Configure electron-builder's electronDownload.arch value to "arm64"
4 Run electron-builder to build the arm64 version of the app.
5 Merge x64 and arm64 versions using @electron/universal
6 Manually signing the merged univeral app

I've built a pkg file with arm64 binary and x64 binary, uploaded it to apple for review, and unfortunately the latest version of electron beta contains some private api calls that cause my app to be rejected. here's the details electron/electron#26480

Anyway, here's how I built it.
3 Configure electron-builder's electronDownload.arch value to "arm64"

Could you elaborate?

This is what I'm using but it seems to ignore --arm64 option and builds an x64 version instead:

electron-builder -m --arm64

I have not defined electronDownload.arch in my package.json and it seems to correctly download the correct electron version when specifying --arm64 and building the Linux version. When building the Mac version it incorrectly compiles for x64 instead.

@warpdesign Currently you must set electronDownload.arch to "arm64" to force the arm64 version of electron to be downloaded.

@gaodeng Unfortunately it still builds for x64 even though I set electronDownload.arch to arm64. Also it rebuilds my native dependencies for x64 too.

Could you share your build configuration and the command you use to start the build?

@warpdesign
If you set up electronDownload.arch correctly, you will end up with the arm64 version of the app, even though the electron builder may have some logs that contain x64 characters during the build process.

For native module, use electron-rebuild -f --arch=arm64 to build arm64 native module and set npmRebuild to false in electron builder configuration file.

Oh you're right, even though it's saying x64 everywhere, it actually built for arm64:

~/ file React-Explorer.app/Contents/MacOS/React-Explorer
React-Explorer.app/Contents/MacOS/React-Explorer: Mach-O 64-bit executable arm64

Thanks for the help!

No wonder it shows x64 in the log, the arch is hardcoded in macPackager.ts:

    if (!hasMas || targets.length > 1) {
      const appPath = prepackaged == null ? path.join(this.computeAppOutDir(outDir, arch), `${this.appInfo.productFilename}.app`) : prepackaged
      nonMasPromise = (prepackaged ? Promise.resolve() : this.doPack(outDir, path.dirname(appPath), this.platform.nodeName as ElectronPlatformName, arch, this.platformSpecificBuildOptions, targets))
        .then(() => this.packageInDistributableFormat(appPath, Arch.x64, targets, taskManager))
    }

@warpdesign Patches to fix the hardcoded values were posted in https://github.com/electron-userland/electron-builder/issues/5392#issuecomment-725779853

Our app has been approved by apple and is live, so I'm going to close the issue.

Our app has been approved by apple and is live, so I'm going to close the issue.

@gaodeng i have sqlite3 issue can you please reply how you have resolved this issue? https://github.com/electron/electron/issues/26364#issuecomment-730956934

@ahmadwaliesipick better-sqlite3 need patch binding.gyp change -std=c++11 to -std=c++14
As for sqlite3, I compiled it smoothly and did not encounter any problems.

@ahmadwaliesipick better-sqlite3 need patch binding.gyp change -std=c++11 to -std=c++14
As for sqlite3, I compiled it smoothly and did not encounter any problems.

@gaodeng how can i apply this patch can you please share details? i am using node-sqlite3 https://github.com/mapbox/node-sqlite3

Are you using better-sqlite3 or sqlite3? From your description, you are using sqlite3. sqlite3 doesn't need any patch to compile. We use both better-sqlite3 and sqlite3 (aka node-sqlite3) in our project. sqlite3 compiles without any problem.

Are you using better-sqlite3 or sqlite3? From your description, you are using sqlite3. sqlite3 doesn't need any patch to compile. We use both better-sqlite3 and sqlite3 (aka node-sqlite3) in our project. sqlite3 compiles without any problem.

@gaodeng Yes i am using node-sqlite3 i have no issue during compile but once i open app then this error shown https://share.getcloudapp.com/geuoxwPq

i have created issue at node-sqlite3 https://github.com/mapbox/node-sqlite3/issues/1396

Do you have info about this issue? @gaodeng

From the error message, it appears that the native module you built is not the arm64 version.
Using electron-rebuild -f --arch=arm64 to build native modules for arm64 architecture, That should solve the problem you are having!

electron-rebuild -f --arch=arm64 to

@gaodeng I have tried that. let me check again. Can you please share which electron-rebuild version you are using?

"electron-rebuild": "^2.3.2",

@gaodeng i am also seeing these issues while rebuild sqlite3. what do you think c++11 not support but sqlite3?
Building module: sqlite3, Completed: 1../src/backup.cc:191:9: warning: unused variable 'status' [-Wunused-variable] int status = napi_create_async_work( ^ ../src/backup.cc:263:5: warning: unused variable 'status' [-Wunused-variable] BACKUP_BEGIN(Step); ^ ../src/macros.h:175:9: note: expanded from macro 'BACKUP_BEGIN' int status = napi_create_async_work( \ ^ ../src/backup.cc:329:5: warning: unused variable 'status' [-Wunused-variable] BACKUP_BEGIN(Finish); ^ ../src/macros.h:175:9: note: expanded from macro 'BACKUP_BEGIN' int status = napi_create_async_work( \ ^ â ¼ Building module: sqlite3, Completed: 13 warnings generated. â ¦ Building module: sqlite3, Completed: 1 CXX(target) Release/obj.target/node_sqlite3/src/database.o â ¸ Building module: sqlite3, Completed: 1../src/database.cc:144:9: warning: unused variable 'status' [-Wunused-variable] int status = napi_create_async_work( ^ ../src/database.cc:240:9: warning: unused variable 'status' [-Wunused-variable] int status = napi_create_async_work( ^ ../src/database.cc:557:9: warning: unused variable 'status' [-Wunused-variable] int status = napi_create_async_work( ^ ../src/database.cc:667:9: warning: unused variable 'status' [-Wunused-variable] int status = napi_create_async_work( ^ â ‹ Building module: sqlite3, Completed: 14 warnings generated. â ¹ Building module: sqlite3, Completed: 1 CXX(target) Release/obj.target/node_sqlite3/src/node_sqlite3.o â § Building module: sqlite3, Completed: 1 CXX(target) Release/obj.target/node_sqlite3/src/statement.o â ¼ Building module: sqlite3, Completed: 1../src/statement.cc:35:21: warning: result of comparison against a string literal is unspecified (use an explicit string comparison function instead) [-Wstring-compare] if (object_type == "Date") { ^ ~~~~~~ ../src/statement.cc:37:28: warning: result of comparison against a string literal is unspecified (use an explicit string comparison function instead) [-Wstring-compare] } else if (object_type == "RegExp") { ^ ~~~~~~~~ ../src/statement.cc:128:9: warning: unused variable 'status' [-Wunused-variable] int status = napi_create_async_work( ^ ../src/statement.cc:188:51: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings] else if (OtherInstanceOf(source.As<Object>(), "RegExp")) { ^ ../src/statement.cc:209:51: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings] else if (OtherInstanceOf(source.As<Object>(), "Date")) { ^ ../src/statement.cc:243:87: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings] else if (!info[start].IsObject() || OtherInstanceOf(info[start].As<Object>(), "RegExp") || OtherInstanceOf(info[start].As<Object>(), "Date") || info[start].IsBu... ^ ../src/statement.cc:243:142: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings] else if (!info[start].IsObject() || OtherInstanceOf(info[start].As<Object>(), "RegExp") || OtherInstanceOf(info[start].As<Object>(), "Date") || info[start].IsBu... ^ ../src/statement.cc:349:5: warning: unused variable 'status' [-Wunused-variable] STATEMENT_BEGIN(Bind); ^ ../src/macros.h:145:9: note: expanded from macro 'STATEMENT_BEGIN' int status = napi_create_async_work( \ ^ ../src/statement.cc:400:5: warning: unused variable 'status' [-Wunused-variable] STATEMENT_BEGIN(Get); ^ ../src/macros.h:145:9: note: expanded from macro 'STATEMENT_BEGIN' int status = napi_create_async_work( \ ^ ../src/statement.cc:471:5: warning: unused variable 'status' [-Wunused-variable] STATEMENT_BEGIN(Run); ^ ../src/macros.h:145:9: note: expanded from macro 'STATEMENT_BEGIN' int status = napi_create_async_work( \ ^ ../src/statement.cc:540:5: warning: unused variable 'status' [-Wunused-variable] STATEMENT_BEGIN(All); ^ ../src/macros.h:145:9: note: expanded from macro 'STATEMENT_BEGIN' int status = napi_create_async_work( \ ^ ../src/statement.cc:640:5: warning: unused variable 'status' [-Wunused-variable] STATEMENT_BEGIN(Each); ^ ../src/macros.h:145:9: note: expanded from macro 'STATEMENT_BEGIN' int status = napi_create_async_work( \ ^ ../src/statement.cc:766:5: warning: unused variable 'status' [-Wunused-variable] STATEMENT_BEGIN(Reset); ^ ../src/macros.h:145:9: note: expanded from macro 'STATEMENT_BEGIN' int status = napi_create_async_work( \ ^ â ´ Building module: sqlite3, Completed: 1../src/statement.cc:243:87: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings] else if (!info[start].IsObject() || OtherInstanceOf(info[start].As<Object>(), "RegExp") || OtherInstanceOf(info[start].As<Object>(), "Date") || info[start].IsBu... ^ ../src/statement.cc:337:26: note: in instantiation of function template specialization 'node_sqlite3::Statement::Bind<node_sqlite3::Statement::Baton>' requested here Baton* baton = stmt->Bind<Baton>(info); ^ ../src/statement.cc:243:142: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings] else if (!info[start].IsObject() || OtherInstanceOf(info[start].As<Object>(), "RegExp") || OtherInstanceOf(info[start].As<Object>(), "Date") || info[start].IsBu... ^ ../src/statement.cc:188:51: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings] else if (OtherInstanceOf(source.As<Object>(), "RegExp")) { ^ ../src/statement.cc:240:45: note: in instantiation of function template specialization 'node_sqlite3::Statement::BindParameter<int>' requested here baton->parameters.push_back(BindParameter((array).Get(i), pos)); ^ ../src/statement.cc:337:26: note: in instantiation of function template specialization 'node_sqlite3::Statement::Bind<node_sqlite3::Statement::Baton>' requested here Baton* baton = stmt->Bind<Baton>(info); ^ ../src/statement.cc:209:51: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings] else if (OtherInstanceOf(source.As<Object>(), "Date")) { ^ ../src/statement.cc:188:51: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings] else if (OtherInstanceOf(source.As<Object>(), "RegExp")) {

Sorry, I'm not an expert on c++ and can't give advice on this issue. But the warning seems to have been there before.

Sorry, I'm not an expert on c++ and can't give advice on this issue. But the warning seems to have been there before.

thanks you so much for your help @gaodeng

May be some C++ expert can help on this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JohnWeisz picture JohnWeisz  Â·  3Comments

leo picture leo  Â·  3Comments

iklemm picture iklemm  Â·  3Comments

mstralka picture mstralka  Â·  3Comments

philcockfield picture philcockfield  Â·  3Comments