Unable to get cabal into a ghcjs (Haskell) environment. ("ghcjs" works fine on its own, but can't get a working "cabal" in there)

As I mentioned in the title, I already have a working environment where ghcjs Main.hs works. I successfully get the compiled .js files. (So this means the below callCabal2nix is successfully parsing the .cabal file.)

However I’m unable to get the actual cabal program in there. Search for “nativeBuildInputs” - there I’ve commented the errors I get. Does anyone know what’s going on?

flake.nix:

{
  description = "my-ghcjs";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        config = {};

        overlays =
          [
            (final: prev:
              {
                myHaskellPkgs = final.haskell.packages."ghcjs".override {
                  overrides = hfinal: hprev:
                      {
                        "my-ghcjs" =
                          hfinal.callCabal2nix "my-ghcjs" ./. {};

                        cryptohash = final.haskell.lib.dontCheck hprev.cryptohash;
                        cryptohash-sha256 = final.haskell.lib.dontCheck hprev.cryptohash-sha256;
                        extra = final.haskell.lib.dontCheck hprev.extra;
                        hinotify = final.haskell.lib.dontCheck hprev.hinotify;
                        html2 = final.haskell.lib.dontCheck hprev.html2;
                        lukko = final.haskell.lib.dontCheck hprev.lukko;
                        resolv = final.haskell.lib.dontCheck hprev.resolv;
                        shelly = final.haskell.lib.dontCheck hprev.shelly;
                        text-short = final.haskell.lib.dontCheck hprev.text-short;
                        zlib = final.haskell.lib.dontCheck hprev.zlib;

                        # Fixed this error:
                        #   Setup: Encountered missing or private dependencies:
                        #   > aeson >=0.8 && <1.6
                        aeson = hprev.aeson_1_5_6_0;

                        cabal-install = final.haskell.lib.dontHaddock (final.haskell.lib.dontCheck hprev.cabal-install);
                      };
                };

                "my-ghcjs" = final.myHaskellPkgs."my-ghcjs";

                myDevShell = final.myHaskellPkgs.shellFor {
                  packages = p: [p."my-ghcjs"];
                  nativeBuildInputs = [
                    # This does not compile ("nix develop" fails). I get the error
                    #
                    # builder for '/nix/store/g0p35p7b06mxvfmx5x1x6807fjm8c67d-cabal-install-3.6.2.0.drv' failed with exit code 1;
                    #  last 10 log lines:
                    #  >
                    #  > SyntaxError: Unexpected token 'void'
                    #  >     at Object.compileFunction (node:vm:352:18)
                    #  >     at wrapSafe (node:internal/modules/cjs/loader:1033:15)
                    #  >     at Module._compile (node:internal/modules/cjs/loader:1069:27)
                    #  >     at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
                    #  >     at Module.load (node:internal/modules/cjs/loader:981:32)
                    #  >     at Function.Module._load (node:internal/modules/cjs/loader:822:12)
                    #  >     at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
                    #  >     at node:internal/main/run_main_module:17:47
                    #
                    # final.myHaskellPkgs.cabal-install

                    # -----

                    # This compiles (gets me into "nix develop" shell), but it only gives me a cabal
                    # that's meant for GHC and not GHCJS because "cabal build" gives this error:
                    #
                    # cabal: The program 'ghc' version >=7.0.1 is required but it could not be
                    # found.
                    #
                    #final.pkgs.cabal-install
                  ];
                };
              }
            )
          ];

        pkgs = import nixpkgs { inherit config system overlays; };
      in {
        packages =
          {
            default = pkgs."my-ghcjs";
            "my-ghcjs" = pkgs."my-ghcjs";
          };

        devShells =
          {
            default = pkgs.myDevShell;
            "my-ghcjs" = pkgs.myDevShell;
          };
      });
}

Main.hs:

module Main where

main :: IO ()
main = do
  putStrLn "hello from ghcjs :)"

my-ghcjs.cabal:

cabal-version:  3.0
name:           my-ghcjs
version:        0.1.0.0
author:         Zeus
maintainer:     zeus@email.xyz

executable my-ghcjs
  main-is: Main.hs
  build-depends:
      ghcjs-base
    , ghcjs-dom
    , jsaddle
    , jsaddle-dom
  hs-source-dirs: ./
  default-language: Haskell2010

flake.lock:

{
  "nodes": {
    "flake-utils": {
      "inputs": {
        "systems": "systems"
      },
      "locked": {
        "lastModified": 1705309234,
        "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
        "owner": "numtide",
        "repo": "flake-utils",
        "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
        "type": "github"
      },
      "original": {
        "owner": "numtide",
        "repo": "flake-utils",
        "type": "github"
      }
    },
    "nixpkgs": {
      "locked": {
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "d3551b986a714071360b75feffa0ce117417f09c",
        "type": "github"
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixpkgs-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "root": {
      "inputs": {
        "flake-utils": "flake-utils",
        "nixpkgs": "nixpkgs"
      }
    },
    "systems": {
      "locked": {
        "lastModified": 1681028828,
        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
        "owner": "nix-systems",
        "repo": "default",
        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
        "type": "github"
      },
      "original": {
        "owner": "nix-systems",
        "repo": "default",
        "type": "github"
      }
    }
  },
  "root": "root",
  "version": 7
}

cc @sorki @Infinisil @cdepillabout

You need to add cabal-install manually. Nixpkgs uses Setup.hs and the Cabal library to build all packages.

1 Like

I think I explained in my post (unless I misunderstood you) how I tried to put cabal-install in there manually (at nativeBuildInputs) and how that didn’t work.

Yeah, I wouldn’t expect cabal-install to build with ghcjs. Just use pkgs.buildPackages.cabal-install, i.e. final.buildPackages.cabal-install in this case.

1 Like

I tried adding your suggested final.buildPackages.cabal-install to nativeBuildInputs, but this gives me the same error as with final.pkgs.cabal-install (which I also mentioned in my OP):

To repeat the cabal build error I get:

cabal: The program 'ghc' version >=7.0.1 is required but it could not be
found.

So for some reason, this cabal seems geared towards GHC and not GHCJS.

FYI (in case it helps), in this environment I have

$ ghcjs --version
The Glorious Glasgow Haskell Compilation System for JavaScript, version 8.10.7 (GHC 8.10.7)

and as already mentioned, ghcjs Main.hs works fine on its own.

Any ideas? I wonder why the “wrong” (GHC) cabal gets in there and how to get the “correct” (GHCJS) cabal in there instead.

cabal-install expects the haskell compiler to be called ghc, so I assume you just need to pass --with-compiler ghcjs explicitly.

1 Like

Unfortunately cabal build --with-compiler ghcjs didn’t work - it gave the error cabal: The program 'ghc-pkg' is required but it could not be found..

However your answer led me to the right path. cabal build --ghcjs works :slight_smile:

Thanks!