Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences in library building with using Cabal and GHC

I'd like to build library from Haskell code, and further use this library (shared library: dll or so) in my C++ project.

I found simple tutorial: http://blogging.makesmeanerd.com/?p=367 And successfull repeat this example.

Further, I simplify this example, and get next code:

{-# LANGUAGE ForeignFunctionInterface #-}

module Grep where

import Foreign
import Foreign.C.String
import Data.Char

printCString :: CString -> IO ()
printCString s = do
    ss <- peekCString s
    putStrLn ss

getCStringFromKey :: IO CString
getCStringFromKey = do
    guess <- getLine
    newCString guess

foreign export ccall printCString :: CString -> IO ()
foreign export ccall getCStringFromKey :: IO CString

It's very simple program. I typed next commands:

>ghc -c -O grep.hs
>ghc -shared -o grep.dll grep.o
Creating library file: grep.dll.a

After, I have a few files: grep.dll, grep.dll.a and grep_stub.h (header file for my C++ project). I successfull use this library in C++ project. C++ code is very simple (I used MS Visual Studio):

#include <iostream>
#include <string>
#include "grep_stub.h"

int main(int argc, char* argv[])
{
    std::string testStr;
    hs_init(&argc, &argv);
    HsPtr str1 = getCStringFromKey();
    std::cout << "We've get from Haskell: " << (char*)str1 << std::endl;

    HsPtr ss = "Hello from C++!";
    printCString(ss);

    std::cout << "Test application" << std::endl;
    std::cin.get();
    hs_exit();
    return 0;
}

After compilation, this code works very well.

If I build same Haskell code (grep.hs) with using Cabal build system:

name:                grep
version: 1.0
synopsis:            example shared library for C use
build-type:          Simple
cabal-version:       >=1.10

library
  default-language:    Haskell2010
  exposed-modules:     Grep
  extra-libraries:     HSrts-ghc7.6.3
  extensions: ForeignFunctionInterface 
  build-depends:       base >= 4

And run Cabal build system:

>cabal configure --enable-shared
>cabal build
...
Creating library file: dist\build\libHSgrep-1.0-ghc7.6.3.dll.a

I got another dll (with small size), but I can't use this dll in MS VS, because I get a lot of linker errors (ever if I get dll.a files from Haskell Platform).

Main questions:

  • What is difference between build library with Cabal and ghc?
  • How can I build the same dll with Cabal, as I get with GHC?
like image 722
Simplex Avatar asked May 08 '14 13:05

Simplex


1 Answers

You can set additional options in the cabal file by adding ghc-options to your library settings. Not sure what is needed in your case, but I have run into the same issue (small lib, linker errors) and for me the following setting solved it:

ghc-options: -staticlib

But I use that in an iOS project in Xcode.

like image 149
Andras Avatar answered Sep 20 '22 01:09

Andras