No all.js when compiling with the JS backend?

I’ve created this little nix shell to get the JS enabled GHC:

{
  description = "A pristine single page web app example written in Haskell.";

  inputs =
  {
    nixpkgs.url = "github:nixos/nixpkgs";
  };

  outputs = { self , nixpkgs }:
  {
    devShells.x86_64-linux.default = with import nixpkgs { system = "x86_64-linux"; }; with pkgs;
    let
      ghc = haskell.compiler.ghc9101;
      ghc-js = haskell.compiler.ghc9101.override
      {
        stdenv = stdenv.override { targetPlatform = pkgsCross.ghcjs.stdenv.targetPlatform; };
      };
    in
      mkShell
      {
        packages = [ ghc ghc-js cabal-install ghcid hello ];
        shellHook = ''
          alias ghcjs=javascript-unknown-ghcjs-ghc
          export EMSCRIPTEN_CACHE=$HOME/.emscripten_cache
        '';
      };
  };
}

I’ve made a very simple HelloJS.hs file to test things out:

module Main where

main :: IO ()
main = putStrLn "Hello, JavaScript!"

And have tried to compile it like so:

:> ghcjs HelloJS.hs

[1 of 2] Compiling Main             ( HelloJS.hs, HelloJS.o )
[2 of 2] Linking HelloJS

This is successful, however I’m missing the all.js file from the HelloJS.jsexe directory. Here’s the ls:

:> ls -la HelloJS.jsexe/

total 5292
drwxr-xr-x 2 mastarija users    4096 Apr  2 09:12 .
drwxr-xr-x 7 mastarija users    4096 Apr  2 09:25 ..
-rw-r--r-- 1 mastarija users  227006 Apr  2 09:12 lib.js
-rw-r--r-- 1 mastarija users      21 Apr  2 09:12 out.frefs.js
-rw-r--r-- 1 mastarija users       0 Apr  2 09:12 out.frefs.json
-rw-r--r-- 1 mastarija users 4973375 Apr  2 09:12 out.js
-rw-r--r-- 1 mastarija users   22707 Apr  2 09:12 out.stats
-rw-r--r-- 1 mastarija users  174664 Apr  2 09:12 rts.js

From what I’ve read there should be the all.js file, and perhaps even some .html. I’m assuming I’d have to manually create some index.html file and include the rts.js, lib.js and out.js file and call the main function manually to get the output, but I was hoping for something I can quickly test by running e.g. node all.js like I’ve seen in some of the early tutorials.

Did something change in the meantime, is there a flag to enable the all.js generation or have I messed up something in my flake?

Oops. It seems like I’ve made an error in my process. I’ve tried running this initially:

:> ghcjs HelloJS.hs

Which resulted in this error:

[1 of 2] Compiling Main             ( HelloJS.hs, HelloJS.o )
[2 of 2] Linking HelloJS.jsexe
Traceback (most recent call last):
  File "/nix/store/j9nc7hrql549ajmm3n499nlng5g7lb61-emscripten-3.1.73/share/emscripten/emcc.py", line 1651, in <module>
    sys.exit(main(sys.argv))
             ^^^^^^^^^^^^^^
  File "/nix/store/f2krmq3iv5nibcvn4rw7nrnrciqprdkh-python3-3.12.9/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/nix/store/j9nc7hrql549ajmm3n499nlng5g7lb61-emscripten-3.1.73/share/emscripten/emcc.py", line 1644, in main
    ret = run(args)
          ^^^^^^^^^
  File "/nix/store/j9nc7hrql549ajmm3n499nlng5g7lb61-emscripten-3.1.73/share/emscripten/emcc.py", line 684, in run
    return link.run(linker_inputs, options, state, newargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/j9nc7hrql549ajmm3n499nlng5g7lb61-emscripten-3.1.73/share/emscripten/tools/link.py", line 3139, in run
    js_info = get_js_sym_info()
              ^^^^^^^^^^^^^^^^^
  File "/nix/store/f2krmq3iv5nibcvn4rw7nrnrciqprdkh-python3-3.12.9/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/nix/store/j9nc7hrql549ajmm3n499nlng5g7lb61-emscripten-3.1.73/share/emscripten/tools/link.py", line 238, in get_js_sym_info
    with filelock.FileLock(cache.get_path(cache.get_path('symbol_lists.lock'))):
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/j9nc7hrql549ajmm3n499nlng5g7lb61-emscripten-3.1.73/share/emscripten/tools/filelock.py", line 330, in __enter__
    self.acquire()
  File "/nix/store/j9nc7hrql549ajmm3n499nlng5g7lb61-emscripten-3.1.73/share/emscripten/tools/filelock.py", line 278, in acquire
    self._acquire()
  File "/nix/store/j9nc7hrql549ajmm3n499nlng5g7lb61-emscripten-3.1.73/share/emscripten/tools/filelock.py", line 391, in _acquire
    fd = os.open(self._lock_file, open_mode)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 30] Read-only file system: '/nix/store/j9nc7hrql549ajmm3n499nlng5g7lb61-emscripten-3.1.73/share/emscripten/cache/symbol_lists.lock'
javascript-unknown-ghcjs-ghc-9.10.1: `emcc' failed in phase `Linker'. (Exit code: 1)

I’ve then set the emscripten cache in my shellHook to this:

export EMSCRIPTEN_CACHE=$HOME/.emscripten_cache

And I’ve tried to compile again, but instead of running ghcjs I ran ghc which was successful and I thought I’ve fixed the emscripten issue.

So yeah… it’s not that I do not get the all.js generated but the compilation didn’t succeed even though I thought it did.

Anyways, if someone knows what’s wrong with the emscripten thing on nix I’d be very grateful.

Ok. It seems like I’ve figured it out. It seems like I had a wrong name for the emscripten cache environment variable. Here’s my new flake for anyone interested:

{
  description = "A pristine single page web app example written in Haskell.";

  inputs =
  {
    nixpkgs.url = "github:nixos/nixpkgs";
  };

  outputs = { self , nixpkgs }:
  {
    devShells.x86_64-linux.default = with import nixpkgs { system = "x86_64-linux"; }; with pkgs;
    let
      ghc = haskell.compiler.ghc9101;
      ghc-js = haskell.compiler.ghc9101.override
      {
        stdenv = stdenv.override { targetPlatform = pkgsCross.ghcjs.stdenv.targetPlatform; };
      };
    in
      mkShell
      {
        packages = [ ghc ghc-js cabal-install ghcid emscripten ];
        shellHook = ''
          alias ghcjs=javascript-unknown-ghcjs-ghc

          if [ ! -d $(pwd)/.emscripten_cache ]; then
            cp -R ${emscripten}/share/emscripten/cache/ $(pwd)/.emscripten_cache
            chmod u+rwX -R $(pwd)/.emscripten_cache
            export EM_CACHE=$(pwd)/.emscripten_cache
          fi
        '';
      };
  };
}
3 Likes