Level/leveldown

Raspbian Bullseye 64 Bit install error

Mudrekh opened this issue · 9 comments

While trying to install level on a Bullseye raspbian image, I received this error.

npm i level
npm ERR! code 1
npm ERR! path /home/pi/test/node_modules/leveldown
npm ERR! command failed
npm ERR! command sh -c node-gyp-build
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using node-gyp@3.8.0
npm ERR! gyp info using node@16.14.0 | linux | arm64
npm ERR! gyp ERR! configure error
npm ERR! gyp ERR! stack Error: Command failed: /usr/bin/python -c import sys; print "%s.%s.%s" % sys.version_info[:3];
npm ERR! gyp ERR! stack   File "<string>", line 1
npm ERR! gyp ERR! stack     import sys; print "%s.%s.%s" % sys.version_info[:3];
npm ERR! gyp ERR! stack                       ^
npm ERR! gyp ERR! stack SyntaxError: invalid syntax
npm ERR! gyp ERR! stack
npm ERR! gyp ERR! stack     at ChildProcess.exithandler (node:child_process:399:12)
npm ERR! gyp ERR! stack     at ChildProcess.emit (node:events:520:28)
npm ERR! gyp ERR! stack     at maybeClose (node:internal/child_process:1092:16)
npm ERR! gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:302:5)
npm ERR! gyp ERR! System Linux 5.10.92-v8+
npm ERR! gyp ERR! command "/usr/bin/node" "/home/pi/test/node_modules/.bin/node-gyp" "rebuild"
npm ERR! gyp ERR! cwd /home/pi/test/node_modules/leveldown
npm ERR! gyp ERR! node -v v16.14.0
npm ERR! gyp ERR! node-gyp -v v3.8.0
npm ERR! gyp ERR! not ok

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/pi/.npm/_logs/2022-02-17T01_56_54_620Z-debug-0.log

It seems that npm is trying to use node-gyp 3.8.0 which is defined as a sub dependency of another module in my package (sqlite3). Manually installing the latest version of node-gyp (8.x.x) in my package allows the install to complete. This is pretty much a fresh install of Raspbian Lite, but the bizzarre thing is that the same process works fine in an Ubuntu 18.04 system. In an empty folder on Raspbian, level installs perfectly fine, but adding sqlite3 first will cause the build to fail. The annoying part here is that even if I have a global version of node-gyp installed, npm will still use the package defined version of node-gyp when trying to build.

I see that node-gyp is a dev dependency (I assume for prebuilds). Ideally, I would like to not have to specificy node-gyp in my package file directly.. I'm not exactly sure how to approach this problem since node-gyp isn't defined as a normal dependency for leveldown.

It's not a problem with node-gyp. This is related to your version of python. It's trying to use python 3.

@ralphtheninja I agree that its not a problem with node-gyp. Its more so that because another dependency has a specific version of node-gyp installed, npm install uses that version instead of a later version of node-gyp. Since level or any of its sub dependencies don't have a specific version of node-gyp, the build process will use whatever npm resolves with.

By default, I believe Raspbian Bullseye only comes with python3.

Manually installing the latest version of node-gyp (8.x.x) in my package allows the install to complete.

That is the right solution here, as it prevents sqlite's version from being hoisted (i.e. the old node-gyp will be at node_modules/sqlite3/node_modules/node-gyp).

We can't really say leveldown should have node-gyp in its dependencies just because sqlite has it; it's more common to depend on npm's bundled node-gyp (which is tied to the Node.js version that npm itself was bundled with).

The annoying part here is that even if I have a global version of node-gyp installed, npm will still use the package defined version of node-gyp when trying to build.

PS. This is not an npm behavior: npm uses its own bundled node-gyp (which can also be annoying). Preferring a locally-installed node-gyp is a node-gyp-build behavior. For addon authors that dó need a custom version of node-gyp.

The resulting situation is... unfortunate.

@ralphtheninja I agree that its not a problem with node-gyp. Its more so that because another dependency has a specific version of node-gyp installed, npm install uses that version instead of a later version of node-gyp. Since level or any of its sub dependencies don't have a specific version of node-gyp, the build process will use whatever npm resolves with.

By default, I believe Raspbian Bullseye only comes with python3.

Ah! Thanks for clarifying this.

The annoying part here is that even if I have a global version of node-gyp installed, npm will still use the package defined version of node-gyp when trying to build.

PS. This is not an npm behavior: npm uses its own bundled node-gyp (which can also be annoying). Preferring a locally-installed node-gyp is a node-gyp-build behavior. For addon authors that dó need a custom version of node-gyp.

The resulting situation is... unfortunate.

Ok this make sense. Since node-gyp-build is preferring a local dependency, is this something that would make sense specifying then based on the tools level is using? i.e Since using node-gyp-build it makes sense to specific version of node-gyp, otherwise you would normally just rely on the system version?

Another option would be peer dependencies, but Idk how well that would fit. I don't see many packages opt in favor of them.

Ultimately, I'm fine with having to specify the version of node-gyp in the top package file, but I could see other people running into the same problem with other packages, not just sqlite3.

Many (likely most) people don't need node-gyp at all, because we include prebuilt binaries. Otherwise I'd be fine with having an explicit dependency on node-gyp.

Another option would be peer dependencies, but Idk how well that would fit.

Yeah, doesn't fit. Because who's the peer that brings node-gyp?

Latest sqlite3 depends on node-gyp@7 btw, so upgrading sqlite3 could be another option.

Funnily enough, they moved node-gyp 7.x to a peer dependency in github, but sqlite3@5.0.2 (the latest npm version) still has an explicit dependency on node-gyp 3.x which threw me off.

Closing because for the time being, at least until more folks run into issues with this delicate balance of dependencies, I want to keep things as-is.