cabal FFI依赖

Bor*_*ris 14 haskell ffi cabal conio

我正在Windows中制作一个小型Haskell游戏,我希望每次用户按下一个键时都会响应.因为getChar 奇怪的行为在Windows上,我用FFI以访问getchconio.h,描述在这里.相关代码是:

foreign import ccall unsafe "conio.h getch" c_getch :: IO CInt
Run Code Online (Sandbox Code Playgroud)

当我在ghci中运行它或使用ghc编译它时,这很好.我也想尝试制作一个cabal包,所以从这个问题延伸,我在我的cabal文件中包含以下内容:

...
executable noughts
  Includes:          conio.h
  Extra-libraries    conio
...
Run Code Online (Sandbox Code Playgroud)

但是当我跑步时cabal configure,它告诉我:

cabal: Missing dependency on a foreign library:
* Missing C library: conio
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为在我的haskell平台目录下...\Haskell Platform\2012.4.0.0\mingw,目录下有一个conio.h文件include,但没有其他conio文件提供目标代码.

我是以正确的方式做到这一点,如果是这样,我怎样才能找出要包含在我的cabal文件中的库?

小智 7

首先,C头文件和库之间并不总是一对一的映射.在这种情况下,声明的函数conio.h可以在各种运行时库中找到,例如crtdll(不推荐使用)或msvcrt(首选,我猜).

使用Windows上的Haskell平台,Cabal将在.\mingw\lib(在您的Haskell平台目录下)查找这些库:如果您要求msvcrt,它将寻找.\mingw\lib\libmsvcrt.a.这个特定的库应该已经与您的Haskell平台一起提供.(如果要指向包含lib*.a文件的其他目录,可以使用Cabal的--extra-lib-dirs选项.)

一个很好的例子如下:这是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'
Run Code Online (Sandbox Code Playgroud)

这将是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
Run Code Online (Sandbox Code Playgroud)

这应该工作正常:

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
!
Run Code Online (Sandbox Code Playgroud)