electron / universal

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

mach-o file, but is an incompatible architecture #76

Closed javierguzman closed 9 months ago

javierguzman commented 12 months ago

Hello all,

I have the following in the package.json:

  "scripts": {
    "make-mac": "electron-forge make --platform=darwin --arch=universal",
    }
   ....
   "build": {
    "appId": "whatever",
    "artifactName": "${productName}-${version}.${ext}",
    "linux": {
      "target": [
        "AppImage"
      ],
      "category": "Utility"
    },
    "mac": {
      "entitlements": "./build/entitlements.plist",
      "category": "public.app-category.utilities",
      "target": [
        {
          "target": "dmg",
          "arch": [
            "universal"
          ]
        }
      ]
    }

My electron forge looks like this:

const packagerConfig: ForgePackagerOptions = {
  appBundleId: "whatever",
  darwinDarkModeSupport: true,
  icon: "./build/logo",
  name: "whatever",
  osxUniversal: {
    x64ArchFiles: "*",
  },
  extraResource: ["NEWS.md"]
};

Then I get the error

Uncaught Exception:
Error: dlopen(/Applications/whatever.app/Contents/Resources/app/.webpack/main/native_modules/build/Release/drivelist.node, 0x0001): tried: '/Applications/whatever.app/Contents/Resources/app/.webpack/main/native_modules/build/Release/drivelist.node' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/Applications/whatever.app/Contents/Resources/app/.webpack/main/native_modules/build/Release/drivelist.node' (no such file), '/Applications/whatever.app/Contents/Resources/app/.webpack/main/native_modules/build/Release/drivelist.node' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))
at process.func [as dlopen] (node:electron/js2c/asar_bundle:2:1822)
at Module._extensions..node (node:internal/modules/cjs/loader:1354:18)
at Object.func [as .node] (node:electron/js2c/asar_bundle:2:1822)

Any clue what is it going on?

Thank you in advance and regards

MarshallOfSound commented 9 months ago
  osxUniversal: {
    x64ArchFiles: "*",
  },

This is simply wrong, this is saying "btw you are wrong and every file is an x64 file do whatever you want" rather than letting universal warn you when files aren't correctly split between x64 and arm64. Remove that config line and universal should be warning you about your .node files not being rebuilt as expected

javierguzman commented 9 months ago

And what should I do when I am warned about files not being rebuilt as expected?

MarshallOfSound commented 9 months ago

Rebuild it for the correct architecture? To build a universal app you should be packaging for x64 and arm64 and then stitching them together. Tools like packager and forge will do this for you.

If you're using packager in isolation or spinning your own tooling you'll need to ensure you're calling @electron/rebuild before packaging your app for each architecture and rebuilding your native modules for the right architecture.

javierguzman commented 9 months ago

Thanks @MarshallOfSound , I am using electron forge. So if I leave only the package.json with what I had:

 "mac": {
      "entitlements": "./build/entitlements.plist",
      "category": "public.app-category.utilities",
      "target": [
        {
          "target": "dmg",
          "arch": [
            "universal"
          ]
        }
      ]
    }

Should that be enough? I am not trying myself because I am not anymore in that project and I ended up generating one executable for each architecture. I am curious for future.

MarshallOfSound commented 9 months ago

That doesn't appear to be a forge config

javierguzman commented 9 months ago

That is within the package.json, I remember I saw that in an open source project which was using (presumably) electron/universal correctly. I have just taken another look at the readme of this project and it says to use it like so:

await makeUniversalApp({
  x64AppPath: 'path/to/App_x64.app',
  arm64AppPath: 'path/to/App_arm64.app',
  outAppPath: 'path/to/App_universal.app',
});

Should that go on electron.config.js makers section or where? Thank you again Samuel