2

Possible Duplicate:
How to compile Haskell to a static library?

Anyone have a problem compiling a library using GHC that links to another library?

File:

module TestLib where
foreign export ccall test_me :: IO (Int)
foreign import "mylib_do_test" doTest :: IO ( Int )
test_me = doTest

Output:

> ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.0.4
> ghc TestLib.hs -o test -no-hs-main -L../libmylib -lmylib
Linking test ...
Undefined symbols:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
>

I make the "libmylib.a" library file using "ar -r -s ...".

Community
  • 1
  • 1
Thomas
  • 514
  • 3
  • 10
  • When creating a library, you must not use `--make` mode, so you have to pass `-c` or something similar to tell ghc that it should not link. – Daniel Fischer May 13 '12 at 22:48

1 Answers1

3

As of ghc-7, the default mode is --make. You want to create a library, so you have to tell GHC with the -c flag. You don't need the -no-hs-main then.

 ghc -c TestLib.hs -o test.o

works.

An example:

clib.h:

int doTest(void);

clib.c:

#include "clib.h"

int doTest(void){
    return 42;
}

TestLib.hs:

{-# LANGUAGE ForeignFunctionInterface #-}
module TestLib where

foreign export ccall test_me :: IO (Int)
foreign import ccall "clib.h" doTest :: IO ( Int )
test_me = doTest

libtest.c:

#include <stdio.h>
#include "TestLib_stub.h"

int main(int argc, char *argv[])
{
    hs_init(&argc, &argv);
    printf("%d\n", test_me());
    hs_exit();
    return 0;
}

Compilation and execution:

$ ghc -c -o clib.o clib.c
$ ar -r -s libclib.a clib.o
ar: creating libclib.a
$ ghc TestLib.hs -c -o tlib.o
$ ar -r -s libtlib.a tlib.o
ar: creating libtlib.a
$ ghc -o nltest libtest.c -no-hs-main -L. -ltlib -lclib
$ ./nltest
42

Note: That works as such with ghc >= 7.2; for ghc-7.0.*, you must also compile the generated TestLib_stub.c file and link with TestLib_stub.o.

The important point is to tell ghc not to link when creating the libraries, only when finally the executable is created.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • using "--make" with 6.10.4 would give me a really big static lib with all the modules used linked in. This works but gives a tiny file that must only contain functions from TestLib.hs (when I add other modules in)... Perhaps I need to link on my own now? – Thomas May 10 '12 at 23:34
  • What is it that you want to achieve? `--make` makes it try to link. – Daniel Fischer May 10 '12 at 23:40
  • I want a libtest.a file; so that I can link it with my main C program. – Thomas May 11 '12 at 19:41
  • Okay, that should work with `ghc -c -o libtest.a TestLib.hs` and then `ghc -o prog -no-hs-main yourmain.c libtest.a`. – Daniel Fischer May 11 '12 at 20:46
  • I cannot use GHC it to compile the C library. I also was hoping to avoid using GHC to link to my main executable, but this is less important. Ideally I would use GHC to create a libtest.a that includes the entire Haskell runtime so I can link libtest into anything that needs it without ghc. – Thomas May 14 '12 at 16:10
  • After some more searching, I flagged this as duplicate to http://stackoverflow.com/questions/5131182/how-to-compile-haskell-to-a-static-library – Thomas May 14 '12 at 20:17