Esy: Not installed globally on NixOS

Created on 19 Feb 2019  路  6Comments  路  Source: esy/esy

Operating System:
NixOS 18.09, node 10.15.0, npm 6.8.0

Issue:

After installing esy globally i get an error that esy is not available, same for esy@latest:

位 esy
bash: /home/dejanr/.npm/bin/esy: No such file or directory

Actual behavior:

位 esy
bash: /home/dejanr/.npm/bin/esy: No such file or directory

Expected behavior:
esy is executed

Additional steps to reproduce:

位 npm i -g esy
/home/dejanr/.npm/bin/esy -> /home/dejanr/.npm/lib/node_modules/esy/_build/default/bin/esy.exe

> [email protected] postinstall /home/dejanr/.npm/lib/node_modules/esy/node_modules/esy-solve-cudf
> node ./postinstall.js

> [email protected] postinstall /home/dejanr/.npm/lib/node_modules/esy
> node ./postinstall.js

+ [email protected]
added 3 packages in 1.824s
~ 
位 esy
bash: /home/dejanr/.npm/bin/esy: No such file or directory

Most helpful comment

@dejanr, I have this piece of FHSUserEnv that manages to build the example project. You still need to npm install -g esy@latest manually after entering the shell. Depending on where you put the shell.nix file you may also have to change the path at the bottom (it has $PWD).

{ pkgs ? import <nixpkgs> {} }:

(pkgs.buildFHSUserEnv {
  name = "esy-env";
  targetPkgs = pkgs: (with pkgs;
    [ gnum4
      perl # for shasum
      binutils
      gcc
      gnumake
      curl
      nodejs
      git
      neovim
      which
      ]);
  profile = ''
   export NPM_CONFIG_PREFIX=./vendor/node_modules
   export PATH=$PWD/vendor/node_modules/bin:$PATH
  '';.
}).env

image

Hope this helps, even if it is kinda stopgap and clunky.

All 6 comments

What's in your /home/dejanr/.npm/bin/ or /home/dejanr/.npm/lib directories? Is there anything esy related in there? To be clear is the problem that when you install npm/node with nix, then npm install -g esy doesn't show up in your global path?

The ENOENT that is happening here is not directly related to the paths that are being shown. The thing that is not being found is the linker. If you run readelf -l on the binaries you will see that it says "requesting interpreter: /bin/ld", this doesn't exist on nixos and thus you get the "no such file or directory".

What one could do is to run node2nix over the npm packages and apply patchelf on all binaries fixing up the headers for the binaries, I have a sketch on this lying around:

  patchbin = let esySolveCudfCommandLibs = lib.makeLibraryPath [
         stdenv.cc.cc.lib  # libstdc++.so.6
         ];
    in
     ''
        echo "PATCHING esy"
        patchelf \
          --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
          $out/esy/_build/default/bin/esy.exe
        echo "PATCHING cudf"
        patchelf \
          --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
          --set-rpath "${esySolveCudfCommandLibs}" \
          $out/esy/node_modules/esy-solve-cudf/esySolveCudfCommand.exe
        readelf -l  $out/esy/node_modules/esy-solve-cudf/esySolveCudfCommand.exe

        echo "PATCHING buildpackage"
        patchelf \
          --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
          $out/esy/_build/default/esy-build-package/bin/esyBuildPackageCommand.exe
        readelf -l $out/esy/_build/default/esy-build-package/bin/esyBuildPackageCommand.exe
        echo "PATCHING writePackage"
        patchelf \
          --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
          --set-rpath "${esySolveCudfCommandLibs}" \
          $out/esy/_build/default/esy-build-package/bin/esyRewritePrefixCommand.exe
        readelf -l $out/esy/_build/default/esy-build-package/bin/esyRewritePrefixCommand.exe
       '';

So, this is slightly larger an issue than fixing up paths and such. I think that perhaps the best way of solving this is to package up esy with nix and installing it that way, you already have to bring your own of all of the rest of the ocaml ecosystem.

I really want esy for nixos, perhaps I should give it another try.

@dejanr, I have this piece of FHSUserEnv that manages to build the example project. You still need to npm install -g esy@latest manually after entering the shell. Depending on where you put the shell.nix file you may also have to change the path at the bottom (it has $PWD).

{ pkgs ? import <nixpkgs> {} }:

(pkgs.buildFHSUserEnv {
  name = "esy-env";
  targetPkgs = pkgs: (with pkgs;
    [ gnum4
      perl # for shasum
      binutils
      gcc
      gnumake
      curl
      nodejs
      git
      neovim
      which
      ]);
  profile = ''
   export NPM_CONFIG_PREFIX=./vendor/node_modules
   export PATH=$PWD/vendor/node_modules/bin:$PATH
  '';.
}).env

image

Hope this helps, even if it is kinda stopgap and clunky.

Hi @Reasonable-Solutions, you are right, esy is found inside ~/.npm/bin/esy, but linker is missing. Thanks for your effort on giving possible workarounds. I would probably go with the first approach and make a wrapper for esy with patched linker for now.

位 readelf -l ~/.npm/bin/esy 

Elf file type is EXEC (Executable file)
Entry point 0x6ba5e0
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001f8 0x00000000000001f8  R E    0x8
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001c 0x000000000000001c  R      0x1
      **[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]**
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000957c44 0x0000000000957c44  R E    0x200000
  LOAD           0x0000000000957d28 0x0000000000f57d28 0x0000000000f57d28
                 0x00000000005e6d80 0x00000000005fd1b8  RW     0x200000
  DYNAMIC        0x0000000000957de8 0x0000000000f57de8 0x0000000000f57de8
                 0x0000000000000200 0x0000000000000200  RW     0x8
  NOTE           0x0000000000000254 0x0000000000400254 0x0000000000400254
                 0x0000000000000044 0x0000000000000044  R      0x4
  GNU_EH_FRAME   0x0000000000948060 0x0000000000d48060 0x0000000000d48060
                 0x0000000000002ad4 0x0000000000002ad4  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x0000000000957d28 0x0000000000f57d28 0x0000000000f57d28
                 0x00000000000002d8 0x00000000000002d8  R      0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .init_array .fini_array .jcr .data.rel.ro .dynamic .got .got.plt .data .bss 
   04     .dynamic 
   05     .note.ABI-tag .note.gnu.build-id 
   06     .eh_frame_hdr 
   07     
   08     .init_array .fini_array .jcr .data.rel.ro .dynamic .got 

I might also try to package esy for nixpkgs, will see how that goes.

Hi there, this one thing isn't fixed yet but shell.nix approach above?

What's in your /home/dejanr/.npm/bin/ or /home/dejanr/.npm/lib directories? Is there anything esy related in there? To be clear is the problem that when you install npm/node with nix, then npm install -g esy doesn't show up in your global path?

Yep, that's right.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bryphe picture bryphe  路  7Comments

jaredly picture jaredly  路  7Comments

bryphe picture bryphe  路  6Comments

zartstrom picture zartstrom  路  3Comments

bryphe picture bryphe  路  5Comments