cabal FFI dependency

cabal, conio, ffi, haskell

Solution

First off, there is not always a one-to-one mapping between C header files and libraries. In this case, the functions declared in `conio.h` can be found in various runtime libraries, such as `crtdll` (deprecated) or `msvcrt` (preferred, I guess).

With the Haskell Platform on Windows, Cabal will look for these libraries in `.\mingw\lib` (under your Haskell Platform directory): if you ask for `msvcrt`, it will look for `.\mingw\lib\libmsvcrt.a`. This specific library should already be shipped with your Haskell Platform. (If you want to point to other directories with `lib*.a` files, you can use Cabal's `--extra-lib-dirs` option.)

A tiny example of this would be as follows; this is `Main.hs`:

{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.C.Types
foreign import ccall unsafe "conio.h _putch" c_putch :: CInt -> IO ()

main :: IO ()
main = do
    c_putch . toEnum . fromEnum $ '!'
    c_putch . toEnum . fromEnum $ '\n'

And this would be `something-awesome.cabal`:

name:                something-awesome
version:             0.1.0.0
build-type:          Simple
cabal-version:       >=1.8

executable yay
  main-is:             Main.hs
  build-depends:       base ==4.5.*

  includes:            conio.h
  extra-libraries:     msvcrt

This should work fine:

c:\tmp\something-awesome> dir /B
Main.hs
something-awesome.cabal

c:\tmp\something-awesome> cabal configure
Resolving dependencies...
Configuring something-awesome-0.1.0.0...

c:\tmp\something-awesome> cabal build
Building something-awesome-0.1.0.0...
Preprocessing executable 'yay' for something-awesome-0.1.0.0...
[1 of 1] Compiling Main             ( Main.hs, dist\build\yay\yay-tmp\Main.o )
Linking dist\build\yay\yay.exe ...

c:\tmp\something-awesome> dist\build\yay\yay.exe
!

Problem

I am making a small Haskell game in Windows, where I would like to respond each time the user presses a key. Because `getChar` behaves strangely on Windows, I use FFI to get access to `getch` in `conio.h`, as described here. The relevant code is: ``` foreign import ccall unsafe "conio.h getch" c_getch :: IO CInt ``` This works fine, when I run it in ghci, or compile it with ghc. I also want to try making a cabal package out of it, so extending from this question, I include the following in my cabal file: ``` ... executable noughts Includes: conio.h Extra-libraries conio ... ``` But when I run `cabal configure`, it tells me: ``` cabal: Missing dependency on a foreign library: * Missing C library: conio ``` It makes sense, because in my haskell platform directory, under `...\Haskell Platform\2012.4.0.0\mingw` there is a `conio.h` file under the `include` directory, but no other `conio` file to provide the object code. Am I doing this the right way, and if so, how can I find out which library to include in my cabal file?

Original source

Related problems