Obtain location for "HsFFI.h"

Obtain location for “HsFFI.h”

On developing a Haskell program that is invoked from C, we include the header HsFFI.h and use its definitions to initiate and exit the haskell runtime when executing the main function from C:

-- Safe.hs
{-# LANGUAGE ForeignFunctionInterface #-}

module Safe where

import Foreign.C.Types

fibonacci :: Int -> Int
fibonacci n = fibs !! n
  where
    fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral

foreign export ccall fibonacci_hs :: CInt -> CInt

The c code:

// main.c
#include <HsFFI.h>
#ifdef __GLASGOW_HASKELL__
#include "Safe_stub.h"
#endif
#include <stdio.h>

int main(int argc, char *argv[]) {
    int i;
    hs_init(&argc, &argv);

    i = fibonacci_hs(42);
    printf("Fibonacci: %d\n", i);

    hs_exit();
    return 0;
}

Then we compile with ghc, generating the Safe_stub.h header file, and then test.out:

$ ghc -c -O Safe.hs
$ ghc --make -no-hs-main -optc-O main.c Safe -o test.out
$ ./test.out
Fibonacci: 267914296

My issue is, my IDE can’t find the location of HsFFI.h based on the normal include path, so I’d like to extend it. My first attempt is to create a variable in my shell.nix for it:

with import <nixpkgs> { };
clangStdenv.mkDerivation {
  name = "laud";
  buildInputs = with pkgs; [
    llvm
    llvmPackages.bintools
    # For haskell
    ghc
    haskell-language-server
  ];
  MY_GHC_INCLUDE_DIR = "/nix/store/dflk9i1b2njqsjy9q9m45q1w50q66fpc-ghc-9.10.3/lib/ghc-9.10.3/lib/x86_64-linux-ghc-9.10.3/rts-1.0.2/include";
}

With this I can use the $MY_GHC_INCLUDE_DIR variable to point to the header location. I got this information to where it is by following this blog

ghc-pkg field rts include-dirs --simple-output

which gave me where HsFFI.h is located.

Now is there a nix way to get this env var into my shell without hardcoding that nix store path?