
On Mon, Feb 26, 2007 at 01:02:57PM -0800, Evan Laforge wrote:
Question #1 is compiling FFI using modules. I'd like to use ghc --make for the speed and convenience, but obviously it doesn't know how to compile the C. So my hybrid approach has been to write a makefile for the C, and then make the haskell program depend on the .o files and invoke ghc --make on them, like so:
_dummy_target: cfile.o ghc -Ic_includes -Lc_libs --make -main-is HsMain -o target HsMain.hs cfile.o -lclib
Unfortunately, ghc doesn't seem relink the target if cfile.o changed, so as a hack I put 'rm target' before the ghc line to make it link every time.
Does anyone have a better solution?
Yeah. GHC knows how to call GCC on .c files, so just do: ghc -Ic_includes -Lc_libs --make -main-is HsMain -o target HsMain.hs cfile.c -lclib Don't worry about recompilation checking, GCC is two orders of magnitude faster than GHC so the extra time will be neglible unless your program is 95% C.
#2 is structs. What's a good way to marshal structs? The straightforward way would be C stubs like "T get_t(struct foo *x)" for every field of the struct, but clearly at any kind of scale something like greencard will be necessary (as an aside, greencard's last update seems to have been "support this newfangled FFI"... is it still alive and just "done" or are people using something else nowadays?). Hopefully in can be made efficient though (I don't know if cross C-haskell inlining will happen, but maybe with -fvia-c?). The other issue is that the haskell type will not be Storable, so the Foreign.Array stuff won't work... I need a separate sizeof C stub and allocaBytes.
It's much easier to declare e.g. "type SomeCStruct = Word64" and then use Bits to pick out the fields in pure haskell, but I imagine this assumes way too much about how the struct is layed out in memory.
I don't know about GreenCard, but hsc2hs is still very much alive and also addresses that goal.