Julusian / node-midi

A node.js wrapper for RtMidi providing MIDI I/O
https://www.npmjs.com/package/@julusian/midi
MIT License
22 stars 7 forks source link

Unhandled rejection in Forge #17

Open RichardFoss opened 4 months ago

RichardFoss commented 4 months ago

Hi, I have been using your great MIDI module for some time. I recently moved to Electron, and my code runs when started from the VSCode terminal. However when using Forge to package my application, I get the following error:

An unhandled rejection has occurred inside Forge: Error: node-gyp failed to rebuild '/private/var/folders/nm/rd3fmgk15c30njwgmn41h3wm0000gp/T/electron-packager/darwin-x64/ImmerGo-MOTU-darwin-x64-6kin7Y/Electron.app/Contents/Resources/app/node_modules/@julusian/midi'

I do have Python 3 installed and have used node-gyp successfully.

Julusian commented 4 months ago

I don't use forge myself, so I am not certain on the exact solution here. That error doesn't say anything about why it failed, so I don't have any ideas on how to fix the rebuild.

But I think there is a way to tell forge to not rebuild this library. This library already provides electron compatible binaries, with os targets chosen for maximum compatibility.

RichardFoss commented 4 months ago

Thanks for getting back to me on this Julian. There is a rebuild option one can use, both in the make command and in the forge config file. I have tried both, but get the same result. It's good to know that electron compatible binaries are in the library. I am trying to create an x64 package on an arm64 machine. This might be the problem.

lozjackson commented 3 months ago

@RichardFoss We had a similar error which was solved by downgrading Python from 3.12.x to 3.11.x

Try checking which Python version you're running.

I think there is a conflict/incompatibility between the version of node-gyp that electron/forge uses and Python 3.12

RichardFoss commented 3 months ago

Thanks, I appreciate you getting back to me about this issue! I do have Python 3.11 installed. I eventually decided to find an Intel Mac machine and built on that. I haven't been able to build an x64 package on a Mac silicon machine.

RichardFoss commented 3 months ago

Hi again, I'm having another go at generating my app package for x64 Mac on an arm64 Mac. I have done the following:

  1. Opened a terminal set to Rosetta and launched VSCode from this terminal. In a VSCode terminal, typing arch returns i386
  2. Installed node.js, and checked whether it was running x64 code - node -p "process.arch" returned x64
  3. Checked that I had Python 3 installed for x64 with this command python-intel64
  4. Set the PYTHON environment variable to point to Python 3 - export PYTHON=$(which python3-intel64)
  5. Issued an npm install When I do an npm start to run my app, I get the following: App threw an error during load Error: dlopen(/Users/csrf/Documents/Git-Repos/ImmerGo-Presonus-SL-Electron-Intel/immergo-presonus-sl-electron/node_modules/@julusian/midi/build/Release/midi.node, 0x0001): tried: '/Users/csrf/Documents/Git-Repos/ImmerGo-Presonus-SL-Electron-Intel/immergo-presonus-sl-electron/node_modules/@julusian/midi/build/Release/midi.node' (mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e))) I see that there are 8 prebuilds, including midi-darwin-x64. What I can't understand is why the loader is indicating that it needs arm64e. I have a feeling that the problem might have to do with the bindings, but don't understand the binding mechanism. Would appreciate some help with this, thanks!
Julusian commented 3 months ago

tried: '/Users/csrf/Documents/Git-Repos/ImmerGo-Presonus-SL-Electron-Intel/immergo-presonus-sl-electron/node_modules/@julusian/midi/build/Release/midi.node'

This is suspicious to me. This means it decided to recompile the library rather than use the prebuild version. If there is a locally compiled version, it will always use that instead of the prebuilds (the assumption is that it was compiled because the prebuild failed to load, most likely because of minimum os requirements. or its a development build of the module)

In me experience, tools do not provide the correct flags to get node-gyp to compile for a different architecture than node is running. Something such as electron-rebuild will rebuild every native module, ignoring the fact that there are prebuilds, and in the process will generate this platform specific binary for whatever platform you told electron to generate, resulting in it then being wrong for your machine

Could you try deleting the node_modules folder and doing step 5 again?

RichardFoss commented 3 months ago

Thank you very much for the quick response! I removed node_modules, cleared the npm cache and did an npm install. Unfortunately had the same error. Here it is more fully: App threw an error during load Error: dlopen(/Users/csrf/Documents/Git-Repos/ImmerGo-Presonus-SL-Electron-Intel/immergo-presonus-sl-electron/node_modules/@julusian/midi/build/Release/midi.node, 0x0001): tried: '/Users/csrf/Documents/Git-Repos/ImmerGo-Presonus-SL-Electron-Intel/immergo-presonus-sl-electron/node_modules/@julusian/midi/build/Release/midi.node' (mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e))) at process.func [as dlopen] (node:electron/js2c/asar_bundle:2:1822) at Module._extensions..node (node:internal/modules/cjs/loader:1326:18) at Object.func [as .node] (node:electron/js2c/asar_bundle:2:1822) at Module.load (node:internal/modules/cjs/loader:1096:32) at Module._load (node:internal/modules/cjs/loader:937:12) at f._load (node:electron/js2c/asar_bundle:2:13330) at Module.require (node:internal/modules/cjs/loader:1120:19) at require (node:internal/modules/cjs/helpers:103:18) at loadBinding (/Users/csrf/Documents/Git-Repos/ImmerGo-Presonus-SL-Electron-Intel/immergo-presonus-sl-electron/node_modules/pkg-prebuilds/bindings.js:93:12) at Object. (/Users/csrf/Documents/Git-Repos/ImmerGo-Presonus-SL-Electron-Intel/immergo-presonus-sl-electron/node_modules/@julusian/midi/midi.js:1:47)

RichardFoss commented 3 months ago

From your text - "In me experience, tools do not provide the correct flags to get node-gyp to compile for a different architecture than node is running.". So node is running on the x64 simulated machine, and will build an x64 midi.node. It seems that the loader recognizes this - "Release/midi.node' (mach-o file, but is an incompatible architecture (have (x86_64), ". But then why would it need an arm64 build? - "need (arm64e)))"?

RichardFoss commented 3 months ago

It would seem that dlopen wants to load an arm64 midi.node?

Julusian commented 3 months ago

Good point, that suggests that it is actually running an arm64 version of node. That error (mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e))) is definitely produced by nodejs when it tries to load the native file and fails.