Is there a way to build dynamic libraries in jhc such they're linkable and callable from a C driver? I'm hoping to write a bridge between ruby and haskell, and GHC's dynamic lib support seems a bit sketchy currently. Cheers Mark
On Thu, Aug 06, 2009 at 05:22:06PM +1000, Mark Wotton wrote:
Is there a way to build dynamic libraries in jhc such they're linkable and callable from a C driver? I'm hoping to write a bridge between ruby and haskell, and GHC's dynamic lib support seems a bit sketchy currently.
If your interface is constrained to things expressible in the FFI spec, then you can 'foreign export' whatever functions you like from haskell then compile the resulting C file into a shared library. I don't have a specific option that does this automatically, but it should be easy to do by hand once you see the C file it produces. Let me know what issues you run into, if we can come up with a generally useful 'recipe' for creating shared libraries from haskell I'd like to add it as an explicit command line option to jhc. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/
On 06/08/2009, at 6:11 PM, John Meacham wrote:
On Thu, Aug 06, 2009 at 05:22:06PM +1000, Mark Wotton wrote:
Is there a way to build dynamic libraries in jhc such they're linkable and callable from a C driver? I'm hoping to write a bridge between ruby and haskell, and GHC's dynamic lib support seems a bit sketchy currently.
If your interface is constrained to things expressible in the FFI spec, then you can 'foreign export' whatever functions you like from haskell then compile the resulting C file into a shared library. I don't have a specific option that does this automatically, but it should be easy to do by hand once you see the C file it produces. Let me know what issues you run into, if we can come up with a generally useful 'recipe' for creating shared libraries from haskell I'd like to add it as an explicit command line option to jhc.
Colour me shocked, if I just comment out the main function, the
exported functions work fine.
Thanks, this is really helpful. I'd like to see if other packages work
as well - how do you enable extra libraries like containers?
jhc --list-libraries shows that containers-0.2.0 is there, but when i
try to compile a program with Data.Map calls in it, jhc complains
bitterly:
mwotton@ubuntu-vm:/mnt/hgfs/projects/rhaskell/linux$ jhc -v Test.hs
reading /usr/local/etc/jhc-0.6/targets.ini
reading /usr/local/etc/jhc-0.6/targets.ini
jhc -v Test.hs
jhc 0.6.1 (0.6.0-32)
Compiling [Right "Test.hs"]
Loading libraries: ["base","haskell98"]
Library: base-1.0
Library: haskell98-1.0
Test.hs:1 - Warning: The pragma 'LANGUAGE' is unknown
Main [Test.hs]
On Fri, Aug 07, 2009 at 12:32:22PM +1000, Mark Wotton wrote:
Colour me shocked, if I just comment out the main function, the exported functions work fine.
Cool! I was hoping it would be that easy but wasn't quite sure as I have never tested it. I guess the only thing to get jhc to officially support creating C librares would be to add an option that will omit main and call gcc with slightly different options to compile a library. If we want to get fancy we could have it spit out an appropriate .h file as well :) I would happily help if someone wanted to work on this. It fits right in with jhc's strengths.
Thanks, this is really helpful. I'd like to see if other packages work as well - how do you enable extra libraries like containers?
you use the '-p' option like '-pcontainers'. The p stands for 'package'. I sometimes call libraries packages and vice versa. I had some reasoning for this back in the day, but it may no longer be relevant, what do people think I should do to clean up the terminology? Note that I am completely overhauling the ho file format and library support to make jhc signifigantly faster at loading them and more memory efficient. Among other things, the type checking information can be loaded independently so jhc can go through and typecheck your entire project in seconds before it starts trying to compile anything, this should greatly help the user experince when in a 'compile-test' loop. As an indicator of speed, jhc will typecheck _all_ of base from scratch in less than a minute. So no need to baby sit your large compiles. if it gets past the first minute, you can go on your coffee break and know it won't run into a type error half way through. As a side effect, libraries are currently broken in the darcs repository version of jhc, but I am working on that as well as a 'jhc-pkg' tool to help maintain them. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/
John Meacham wrote:
you use the '-p' option like '-pcontainers'. The p stands for 'package'. I sometimes call libraries packages and vice versa. I had some reasoning for this back in the day, but it may no longer be relevant, what do people think I should do to clean up the terminology?
even GHC has/had this confusion. What's the difference anyway? Well I guess a package can be an executable program, or can be a library. I doubt the terminology makes much difference, just pick something consistent. Maybe you use '-p' and not '-l' so that '-l' can mean exactly what it means to the C compiler? -Isaac
On 07/08/2009, at 1:18 PM, John Meacham wrote:
On Fri, Aug 07, 2009 at 12:32:22PM +1000, Mark Wotton wrote:
Colour me shocked, if I just comment out the main function, the exported functions work fine.
Cool! I was hoping it would be that easy but wasn't quite sure as I have never tested it.
I guess the only thing to get jhc to officially support creating C librares would be to add an option that will omit main and call gcc with slightly different options to compile a library. If we want to get fancy we could have it spit out an appropriate .h file as well :)
I would happily help if someone wanted to work on this. It fits right in with jhc's strengths.
Awesome. I'm going to get a first, ugly-as-sin cut of this going first, just so i can demo Ruby calling Haskell and work out if there are any other big obstacles, but I'd be happy to come back and have a go at doing it in a more principled way.
Thanks, this is really helpful. I'd like to see if other packages work as well - how do you enable extra libraries like containers?
you use the '-p' option like '-pcontainers'. The p stands for 'package'. I sometimes call libraries packages and vice versa. I had some reasoning for this back in the day, but it may no longer be relevant, what do people think I should do to clean up the terminology?
so long as it's docced (as it was when i went digging further, sorry about that) it's fine.
Note that I am completely overhauling the ho file format and library support to make jhc signifigantly faster at loading them and more memory efficient. Among other things, the type checking information can be loaded independently so jhc can go through and typecheck your entire project in seconds before it starts trying to compile anything, this should greatly help the user experince when in a 'compile-test' loop. As an indicator of speed, jhc will typecheck _all_ of base from scratch in less than a minute. So no need to baby sit your large compiles. if it gets past the first minute, you can go on your coffee break and know it won't run into a type error half way through.
As a side effect, libraries are currently broken in the darcs repository version of jhc, but I am working on that as well as a 'jhc-pkg' tool to help maintain them.
Ah, excellent.
Another dumb newbie question: what does this error mean?
mwotton@ubuntu-vm:/mnt/hgfs/projects/rhaskell/linux$ jhc -vvv Test.hs
-pcontainers
reading /usr/local/etc/jhc-0.6/targets.ini
reading /usr/local/etc/jhc-0.6/targets.ini
jhc -vvv Test.hs -pcontainers
jhc 0.6.1 (0.6.0-32)
Compiling [Right "Test.hs"]
Loading libraries: ["base","haskell98","containers"]
Library: base-1.0
Library: haskell98-1.0
Library: containers-0.2.0
Test.hs:1 - Warning: The pragma 'LANGUAGE' is unknown
Main [Test.hs]
On Fri, Aug 07, 2009 at 01:37:22PM +1000, Mark Wotton wrote:
Another dumb newbie question: what does this error mean?
mwotton@ubuntu-vm:/mnt/hgfs/projects/rhaskell/linux$ jhc -vvv Test.hs -pcontainers reading /usr/local/etc/jhc-0.6/targets.ini reading /usr/local/etc/jhc-0.6/targets.ini jhc -vvv Test.hs -pcontainers jhc 0.6.1 (0.6.0-32) Compiling [Right "Test.hs"] Loading libraries: ["base","haskell98","containers"] Library: base-1.0 Library: haskell98-1.0 Library: containers-0.2.0 Test.hs:1 - Warning: The pragma 'LANGUAGE' is unknown Main [Test.hs]
Stale: Fresh: Stale: user error (don't know this file) this is after importing Data.Map. Removing that line from Test.hs removes the error - is my libraries install broken somehow?
Hmm.. yeah, that means it thinks the 'containers' library is out of date for some reason, which it shouldn't as libraries don't go out of date. How did you install? via a tarball or rpm? it is possible I accidentally included a stale '.hl' in a distribution. Or do you have any files like Data/Map.hs sitting around that would conflict with something inside of the hl file? that also could possibly make jhc think the library was stale. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/
On 07/08/2009, at 1:43 PM, John Meacham wrote:
On Fri, Aug 07, 2009 at 01:37:22PM +1000, Mark Wotton wrote:
Another dumb newbie question: what does this error mean?
mwotton@ubuntu-vm:/mnt/hgfs/projects/rhaskell/linux$ jhc -vvv Test.hs -pcontainers reading /usr/local/etc/jhc-0.6/targets.ini reading /usr/local/etc/jhc-0.6/targets.ini jhc -vvv Test.hs -pcontainers jhc 0.6.1 (0.6.0-32) Compiling [Right "Test.hs"] Loading libraries: ["base","haskell98","containers"] Library: base-1.0 Library: haskell98-1.0 Library: containers-0.2.0 Test.hs:1 - Warning: The pragma 'LANGUAGE' is unknown Main [Test.hs]
Stale: Fresh: Stale: user error (don't know this file) this is after importing Data.Map. Removing that line from Test.hs removes the error - is my libraries install broken somehow?
Hmm.. yeah, that means it thinks the 'containers' library is out of date for some reason, which it shouldn't as libraries don't go out of date.
How did you install? via a tarball or rpm? it is possible I accidentally included a stale '.hl' in a distribution. Or do you have any files like Data/Map.hs sitting around that would conflict with something inside of the hl file? that also could possibly make jhc think the library was stale.
the 0.6.1 tarball. No files named Map.hs in that directory, possibly somewhere else on the filesystem but I'm not sure where jhc looks. should i grab the libs from darcs, or are they broken? mark
On Fri, Aug 07, 2009 at 01:51:12PM +1000, Mark Wotton wrote:
Hmm.. yeah, that means it thinks the 'containers' library is out of date for some reason, which it shouldn't as libraries don't go out of date.
How did you install? via a tarball or rpm? it is possible I accidentally included a stale '.hl' in a distribution. Or do you have any files like Data/Map.hs sitting around that would conflict with something inside of the hl file? that also could possibly make jhc think the library was stale.
the 0.6.1 tarball. No files named Map.hs in that directory, possibly somewhere else on the filesystem but I'm not sure where jhc looks. should i grab the libs from darcs, or are they broken?
Hmm.. I must have had a stale containers when I put together that tarball. A quick workaround would be to pull the containers source with ; darcs get http://darcs.haskell.org/packages/containers then add -icontainers to the command line, it will then use the files directly out of said directory. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/
On 07/08/2009, at 2:03 PM, John Meacham wrote:
On Fri, Aug 07, 2009 at 01:51:12PM +1000, Mark Wotton wrote:
the 0.6.1 tarball. No files named Map.hs in that directory, possibly somewhere else on the filesystem but I'm not sure where jhc looks. should i grab the libs from darcs, or are they broken?
Hmm.. I must have had a stale containers when I put together that tarball.
A quick workaround would be to pull the containers source with
; darcs get http://darcs.haskell.org/packages/containers
then add -icontainers to the command line, it will then use the files directly out of said directory.
Heh, probably shouldn't have tried to build that on a VM. think it ran out of memory a long time before it came close :) oh, also, jhc won't run on Mac OS, it's missing a header file 17:35 ~/src/jhc-0.6.1 % cat Foo.hs main = putStrLn "foo" 17:35 ~/src/jhc-0.6.1 % jhc Foo.hs Optimize.optimize.let-shrink-tail Optimize.optimize.unit-unit Optimize.optimize.unit-unit Optimize.optimize.let-unbox-const.{&("CJhc.Basics.()") hs.out_code.c:62:20: error: endian.h: No such file or directory user error (C code did not compile.) I do have these files: /usr/include/i386/endian.h /usr/include/machine/endian.h /usr/include/ppc/endian.h /usr/include/sys/_endian.h mark
On 07/08/2009, at 1:18 PM, John Meacham wrote:
On Fri, Aug 07, 2009 at 12:32:22PM +1000, Mark Wotton wrote:
Colour me shocked, if I just comment out the main function, the exported functions work fine.
Cool! I was hoping it would be that easy but wasn't quite sure as I have never tested it.
I guess the only thing to get jhc to officially support creating C librares would be to add an option that will omit main and call gcc with slightly different options to compile a library. If we want to get fancy we could have it spit out an appropriate .h file as well :)
I would happily help if someone wanted to work on this. It fits right in with jhc's strengths.
Ok, so I could probably do with a hand on this :)
I've hacked Main.hs and FromHs.hs so that if there's no main, it
silently ignores it and omits it from the list. (Obviously
this is sub-optimal, but it'll do for now until I have some clue what
I'm doing.)
My code works fine if I do actually have a main, but when I try on
code without, I get a rather confusing error message:
==============================================================
15:51 ~/projects/Hubris/sample % cat Test.hs
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.C.Types
import Maybe
fibonacci :: Int -> Int
fibonacci n = fibs !! n
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral
foreign export ccall fibonacci_hs :: CInt -> CInt
15:51 ~/projects/Hubris/sample % ~/src/jhc/jhc -v Test.hs
reading /usr/local/etc/jhc-0.6/targets.ini
reading /usr/local/etc/jhc-0.6/targets.ini
jhc -v Test.hs
jhc 0.6.2 (-n byxkainijid-8
)
Finding Dependencies...
Loading libraries: ["base","haskell98"]
Library: base-1.0
Library: haskell98-1.0
Main [Test.hs]
On Mon, Aug 10, 2009 at 03:55:17PM +1000, Mark Wotton wrote:
On 07/08/2009, at 1:18 PM, John Meacham wrote: I've hacked Main.hs and FromHs.hs so that if there's no main, it silently ignores it and omits it from the list. (Obviously this is sub-optimal, but it'll do for now until I have some clue what I'm doing.)
Hi, you should try the latest patch bundle I sent to the list, I created appropriate hs_init() and hs_exit() functions that you should call and ensured that the global CAFs get initialized properly in the absence of 'main'. If you compile the C code with -D_JHC_STANDALONE=0 then it should omit the main function from the source code. I didn't change anything else, so you will still need a dummy 'Main.main' for now. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/
On 06/08/2009, at 6:11 PM, John Meacham wrote:
On Thu, Aug 06, 2009 at 05:22:06PM +1000, Mark Wotton wrote:
Is there a way to build dynamic libraries in jhc such they're linkable and callable from a C driver? I'm hoping to write a bridge between ruby and haskell, and GHC's dynamic lib support seems a bit sketchy currently.
If your interface is constrained to things expressible in the FFI spec, then you can 'foreign export' whatever functions you like from haskell then compile the resulting C file into a shared library. I don't have a specific option that does this automatically, but it should be easy to do by hand once you see the C file it produces. Let me know what issues you run into, if we can come up with a generally useful 'recipe' for creating shared libraries from haskell I'd like to add it as an explicit command line option to jhc.
So, what worked for me was just commenting out the main function and building with -fPIC and -shared from the gcc line from jhc -v. It'd be nice to have a --no-hs-main like GHC has, and a separate C header file listing what's been exported would be cool, but otherwise it was all surprisingly smooth. mark
participants (3)
-
Isaac Dupree -
John Meacham -
Mark Wotton