Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node-gyp-build: /usr/bin/env: bad interpreter: No such file or directory #275

Open
nixinator opened this issue Nov 23, 2021 · 6 comments
Open

Comments

@nixinator
Copy link

nixinator commented Nov 23, 2021

something has either changed in nixpkgs or npm , and things that built are no longer building (such is life).

you can recreate it with the hypercore package here

NixOS/nixpkgs#142196

I'm working on another repo which reports when building with node2nix. :-( . https://discourse.nixos.org/t/nodejs-application-in-nix/16196

> node-gyp-build

sh: /nix/store/pf5dl9n7hsrfzamm16wpzjbf65ic471i-application-0.1.0/lib/node_modules/application/node_modules/.bin/node-gyp-build: /usr/bin/env: bad interpreter: No such file or directory
npm ERR! code ELIFECYCLE
npm ERR! errno 126
npm ERR! [email protected] install: `node-gyp-build`
npm ERR! Exit status 126
npm ERR! 
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

I think the interesting thing here, they are both failing with the same 'bad interpreter' , may be a clue, or may be a red herring.

'in npm space, no one can hear you scream'

@svanderburg
Copy link
Owner

svanderburg commented Dec 14, 2021

This was a really tricky package! As the discourse item describes, you should create an override so that node-gyp-build can be found.

However, what I noticed is that as soon as this dependency is provided, it still attempts to invoke node-gyp-build from the project's node_modules/ folder, and it turns out that the shebang of that executable isn't patched, causing that particular shebang error.

I ended up implementing an override.nix expression that looks as follows:

{pkgs ? import <nixpkgs> {
    inherit system;
}, system ? builtins.currentSystem}:

let
  nodePackages = import ./default.nix {
    inherit pkgs system;
  };
in
nodePackages // {
  hypercore = nodePackages.hypercore.override {
    buildInputs = [ pkgs.nodePackages.node-gyp-build ];
    preRebuild = ''
      sed -i -e "s|#!/usr/bin/env node|#! ${pkgs.nodejs}/bin/node|" node_modules/node-gyp-build/bin.js
    '';
  };
}

with the following command I was able to build it:

$ nix-build -A hypercore

I think the most annoying part is the patchShebangs command in stdenv generic builder in Nixpkgs for some strange reason is unable to detect the shebang line. Even if I directly provide the path to the bin.js file to the patchShebangs command, it still gets ignored.

Fortunately, I manual sed instruction seems to do the trick.

@Artturin
Copy link

Artturin commented Dec 23, 2021

I think the most annoying part is the patchShebangs command in stdenv generic builder in Nixpkgs for some strange reason is unable to detect the shebang line. Even if I directly provide the path to the bin.js file to the patchShebangs command, it still gets ignored.

https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/setup-hooks/patch-shebangs.sh

This setup hook causes the fixup phase to rewrite all script
interpreter file names (`#! /path') to paths found in $PATH. E.g.,
/bin/sh will be rewritten to /nix/store/-some-bash/bin/sh.
/usr/bin/env gets special treatment so that ".../bin/env python" is
rewritten to /nix/store//bin/python. Interpreters that are
already in the store are left untouched.
A script file must be marked as executable, otherwise it will not be
considered.

https://github.com/NixOS/nixpkgs/blob/e95ee1fb3697b67268b0076abc6d74b2d8de6f2a/pkgs/build-support/setup-hooks/patch-shebangs.sh#L51
https://github.com/NixOS/nixpkgs/blob/e95ee1fb3697b67268b0076abc6d74b2d8de6f2a/pkgs/stdenv/generic/setup.sh#L231

@nixinator
Copy link
Author

Great Find! Explains why it's not patching those files, can this behaviour be changed, especially in nodejs is being naughty and not marking scripts with an executable bit. I wonder what other horrible behaviour it has.

@Artturin
Copy link

couple ideas i have:
add a command flag that makes patchShebangs ignore the executable bit and patch regardless
or add a env var that can be set to always patch shebangs

@svanderburg
Copy link
Owner

It would be nice if Nixpkgs' patchShebangs can be fixed or changed with an optional flag to make this possible. In theory, it's also possible to fix it in node-env.nix, but this sort means that we provide a solution to this problem on the wrong level.

I can also image that other packages in Nixpkgs, i.e. non-NPM packages, could run into the similar problems.

@runeksvendsen
Copy link

@svanderburg for some reason your suggested fix doesn't work for me (nor do these instructions). Specifically, the nodePackages expression created by importing ./default.nix does not have any top-level package name attributes (e.g. hypercore). It has only the attributes: args, sources, nodeDependencies, tarball, package, shell. I have tried with both v1.10.0 and v1.9.0 and I get the same results.

The following repo contains the source files (package.json and package-lock.json) from which the rest is generated (default.nix, node-env.nix, node-packages.nix), as well as the override.nix file whose newNodePackages attribute (created by following the guide) doesn't work: https://github.com/runeksvendsen/node2nix-patch-docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants