
I am trying to migrate some old code to cabal. It uses c2hs. Now I wasn't sure I had c2hs installed so I ran cabal anyway. 1. Why isn't configure telling me where c2hs is? It tells me where hsc2hs is! 2. Why is cabal telling me it can't find a source when the source is present? Thanks, Dominic. Here's ping.cabal: Name: Ping Version: 0.0 License: BSD3 Author: Dominic Steinitz Synopsis: The Haskell equivalent of ping Executable: ping Main-Is: test.hs Other-modules: IP_ICMP.chs When I run ./Setup configure, I didn't see any message saying whether c2hs was installed and when I run ./Setup build I get the following: [dom@tility ping]$ ./Setup build Preprocessing executables for Ping-0.0... can't find source for IP_ICMP.chs in ["."] But the source is there: [dom@tility ping]$ ls codes.hs dist/ ip_icmp.h ping.cabal Setup* Setup.hs test.hs CVS/ IP_ICMP.chs Makefile ping.cabal~ Setup.hi Setup.o

I've made some progress. I've installed c2hs. I'm still puzzled as to why ./Setup configure didn't complain. My cabal file is now: Name: Ping Version: 0.0 License: BSD3 Author: Dominic Steinitz Synopsis: The Haskell equivalent of ping Executable: ping Main-Is: test.hs Other-modules: IP_ICMP And cabal magically finds the IP_ICMP.chs file and preprocesses it. However, I need to execute the following: c2hs ip_icmp.h IP_ICMP.chs not just c2hs IP_ICMP.chs How do I get cabal to do this? I saw this http://www.haskell.org//pipermail/haskell/2005-April/015728.html. Does that mean I need to modify cabal? Or can I use UserHooks? Are there any examples? Thanks, Dominic. On Saturday 30 Apr 2005 8:38 am, Dominic Steinitz wrote:
I am trying to migrate some old code to cabal. It uses c2hs. Now I wasn't sure I had c2hs installed so I ran cabal anyway.
1. Why isn't configure telling me where c2hs is? It tells me where hsc2hs is! 2. Why is cabal telling me it can't find a source when the source is present?
Thanks, Dominic.
Here's ping.cabal:
Name: Ping Version: 0.0 License: BSD3 Author: Dominic Steinitz Synopsis: The Haskell equivalent of ping
Executable: ping Main-Is: test.hs Other-modules: IP_ICMP.chs
When I run ./Setup configure, I didn't see any message saying whether c2hs was installed and when I run ./Setup build I get the following:
[dom@tility ping]$ ./Setup build Preprocessing executables for Ping-0.0... can't find source for IP_ICMP.chs in ["."]
But the source is there:
[dom@tility ping]$ ls codes.hs dist/ ip_icmp.h ping.cabal Setup* Setup.hs test.hs CVS/ IP_ICMP.chs Makefile ping.cabal~ Setup.hi Setup.o

Dominic Steinitz
I've made some progress. I've installed c2hs. I'm still puzzled as to why ./Setup configure didn't complain. (snip) And cabal magically finds the IP_ICMP.chs file and preprocesses it. However, I need to execute the following:
c2hs ip_icmp.h IP_ICMP.chs
not just
c2hs IP_ICMP.chs
How do I get cabal to do this? I saw this http://www.haskell.org//pipermail/haskell/2005-April/015728.html. Does that mean I need to modify cabal? Or can I use UserHooks? Are there any examples?
You can do this in a UserHook by either just calling hsc2hs on your .h file in the preBuild phase, or you can override the c2hs preprocessor. As I mention here: http://www.haskell.org//pipermail/haskell/2005-April/015730.html There's an example of using UserHooks to override a preprocessor. Setup.lhs is the right place for the fix until we add more tags to the .cabal file for stuff like this. http://cvs.haskell.org/cgi-bin/cvsweb.cgi/~checkout~/fptools/libraries/Cabal... peace, isaac

On Saturday 30 Apr 2005 4:17 pm, Isaac Jones wrote:
Dominic Steinitz
writes: I've made some progress. I've installed c2hs. I'm still puzzled as to why ./Setup configure didn't complain.
(snip)
And cabal magically finds the IP_ICMP.chs file and preprocesses it. However, I need to execute the following:
c2hs ip_icmp.h IP_ICMP.chs
not just
c2hs IP_ICMP.chs
How do I get cabal to do this? I saw this http://www.haskell.org//pipermail/haskell/2005-April/015728.html. Does that mean I need to modify cabal? Or can I use UserHooks? Are there any examples?
You can do this in a UserHook by either just calling hsc2hs on your .h file in the preBuild phase, or you can override the c2hs preprocessor. As I mention here:
http://www.haskell.org//pipermail/haskell/2005-April/015730.html
There's an example of using UserHooks to override a preprocessor. Setup.lhs is the right place for the fix until we add more tags to the .cabal file for stuff like this.
http://cvs.haskell.org/cgi-bin/cvsweb.cgi/~checkout~/fptools/libraries/Caba l/tests/withHooks/Setup.lhs?rev=1.2;content-type=text%2Fplain
peace,
isaac
Isaac, Thanks for your prompt response. I did have a look at these references before I posted and didn't find them very enlightening. I've now looked at the sources and come up with this which works. Is this the right way to do it? BTW I discovered a bug in the .chs handler. You have "-o " rather than "-o". I can try and send a patch but it might be easier if you edit the file yourself. Dominic. import Distribution.Simple import Distribution.Simple.Utils(rawSystemPath) main = defaultMainWithHooks defaultUserHooks { hookedPreProcessors = [("chs", \_ _ -> myPpC2hs)] } myPpC2hs inFile outFile verbose = rawSystemPath verbose "c2hs" ["-o" ++ outFile, "ip_icmp.h", inFile]

Dominic Steinitz
Isaac,
Thanks for your prompt response. I did have a look at these references before I posted and didn't find them very enlightening.
Was the example test case I gave you helpful? We sorta didn't put the UserHooks in the docs too much because they are a feature that we're not as sure about in the long-term; they're trying to support a lot of different kinds of things, and it'll take time to make sure we get them right. In the meantime, maybe I'll add a little documentation with the warning that things might change.
BTW I discovered a bug in the .chs handler. You have "-o " rather than "-o". I can try and send a patch but it might be easier if you edit the file yourself.
Does "-o " not work? According to the help output, it's correct: Usage: c2hs [ option... ] [header-file] binding-file -C CPPOPTS --cppopts=CPPOPTS pass CPPOPTS to the C preprocessor -c CPP --cpp=CPP use executable CPP to invoke C preprocessor -d TYPE --dump=TYPE dump internal information (for debugging) -h, -? --help brief help (the present message) -i INCLUDE --include=INCLUDE include paths for .chi files -k --keep keep pre-processed C header -o FILE --output=FILE output result to FILE (should end in .hs) -v --version show version information --old-ffi[=OLDFFI] use the FFI without `Ptr a'
import Distribution.Simple import Distribution.Simple.Utils(rawSystemPath)
main = defaultMainWithHooks defaultUserHooks { hookedPreProcessors = [("chs", \_ _ -> myPpC2hs)] }
myPpC2hs inFile outFile verbose = rawSystemPath verbose "c2hs" ["-o" ++ outFile, "ip_icmp.h", inFile]
That looks fine. You could just use "system" instead of rawSystemPath, but since you found it, that's cool. I don't use c2hs myself; is there any pattern to the .h files we might want to preprocess? Any way to derive it from the sources or the module names? I'm not sure how better to support the kind of thing you need. peace, isaac

On Saturday 30 Apr 2005 6:51 pm, Isaac Jones wrote:
Dominic Steinitz
writes: Isaac,
Thanks for your prompt response. I did have a look at these references before I posted and didn't find them very enlightening.
Was the example test case I gave you helpful?
Not really. I needed a simple example like the one I eventually came up with.
We sorta didn't put the UserHooks in the docs too much because they are a feature that we're not as sure about in the long-term; they're trying to support a lot of different kinds of things, and it'll take time to make sure we get them right. In the meantime, maybe I'll add a little documentation with the warning that things might change.
I thought there already was a warning that things might change.
BTW I discovered a bug in the .chs handler. You have "-o " rather than "-o". I can try and send a patch but it might be easier if you edit the file yourself.
Does "-o " not work? According to the help output, it's correct:
I don't understand why but it produced a file called " IP_ICMP.hs". If you run it at the command line c2hs -o IP_ICMP.hs ip_icmp.h IP_ICMP.chs then you get "IP_ICMP.hs" as required. Perhaps something is taking the extra space to be part of the filename?
Usage: c2hs [ option... ] [header-file] binding-file
-C CPPOPTS --cppopts=CPPOPTS pass CPPOPTS to the C preprocessor -c CPP --cpp=CPP use executable CPP to invoke C preprocessor -d TYPE --dump=TYPE dump internal information (for debugging) -h, -? --help brief help (the present message) -i INCLUDE --include=INCLUDE include paths for .chi files -k --keep keep pre-processed C header -o FILE --output=FILE output result to FILE (should end in .hs) -v --version show version information --old-ffi[=OLDFFI] use the FFI without `Ptr a'
import Distribution.Simple import Distribution.Simple.Utils(rawSystemPath)
main = defaultMainWithHooks defaultUserHooks { hookedPreProcessors = [("chs", \_ _ -> myPpC2hs)] }
myPpC2hs inFile outFile verbose = rawSystemPath verbose "c2hs" ["-o" ++ outFile, "ip_icmp.h", inFile]
That looks fine. You could just use "system" instead of rawSystemPath, but since you found it, that's cool.
I don't use c2hs myself; is there any pattern to the .h files we might want to preprocess? Any way to derive it from the sources or the module names? I'm not sure how better to support the kind of thing you need.
I'm not an expert so I really don't know. The author and other users are probably your best bet. My requirement here was to take a system file with a lot of values and use it in Haskell. The c file was called ip_icmp.h so I called the module IP_ICMP. The only other file I have used is in.h and I called the the module IN. I recall that c2hs at that time couldn't swallow netinet/ip_icmp.h and netinet/in.h so I copied them and deleted the offending parts (which I didn't need). Perhaps the modules should have been called Netinet.ICMP and Netinet.IN? I've no idea about Windows. I'm about to recommence work in this area so I'll let you know if anything occurs to me. Dominic.

Dominic Steinitz
BTW I discovered a bug in the .chs handler. You have "-o " rather than "-o". I can try and send a patch but it might be easier if you edit the file yourself.
Does "-o " not work? According to the help output, it's correct:
I don't understand why but it produced a file called " IP_ICMP.hs". If you run it at the command line
c2hs -o IP_ICMP.hs ip_icmp.h IP_ICMP.chs
then you get "IP_ICMP.hs" as required. Perhaps something is taking the extra space to be part of the filename?
Ahh, this is because I passed them as a single argument. I switched it to multiple arguments which should fix it. ie this:
myPpC2hs inFile outFile verbose = rawSystemPath verbose "c2hs" ["-o" ++ outFile, "ip_icmp.h", inFile]
Is now this:
myPpC2hs inFile outFile verbose = rawSystemPath verbose "c2hs" ["-o", outFile, "ip_icmp.h", inFile]
Can you try that out in your hook and see if it works? peace, isaac

On Monday 02 May 2005 6:59 am, Isaac Jones wrote: (snip)
ie this:
myPpC2hs inFile outFile verbose = rawSystemPath verbose "c2hs" ["-o" ++ outFile, "ip_icmp.h", inFile]
Is now this:
myPpC2hs inFile outFile verbose = rawSystemPath verbose "c2hs" ["-o", outFile, "ip_icmp.h", inFile]
Can you try that out in your hook and see if it works? It works.
Two things: 1. I now see the latest version of c2hs says I should put a #include inside the .chs file rather than put the .h file on the command line. So I didn't need to this after all :-( On the positive side, we now have a simple example of using hooks and have fixed a bug. 2. When I run configure, I don't see any message saying where c2hs is. Should I do? Dominic. dom@tility ping]$ ./Setup configure Warning: No license-file field. Configuring Ping-0.0... configure: searching for ghc in path. configure: found ghc at /usr//bin/ghc configure: looking for package tool: ghc-pkg near compiler in /usr//bin/ghc configure: found package tool in /usr//bin/ghc-pkg configure: Using install prefix: /usr/local configure: Using compiler: /usr//bin/ghc configure: Compiler flavor: GHC configure: Compiler version: 6.4 configure: Using package tool: /usr//bin/ghc-pkg configure: Using haddock: /usr//bin/haddock configure: No happy found configure: No alex found configure: Using hsc2hs: /usr//bin/hsc2hs configure: No cpphs found configure: Reading installed packages...

On Sat, 2005-04-30 at 10:51 -0700, Isaac Jones wrote:
I don't use c2hs myself; is there any pattern to the .h files we might want to preprocess? Any way to derive it from the sources or the module names?
Basically no. The .h file is usually an installed system headder file. For example for gtk2hs, we've got one .h file per package (and all .chs files in the package use the same .h file - though this is not essential). For example the gtk package uses gtk/gtk.h with: -DXTHREADS -D_REENTRANT -DXUSE_MTSAFE_API -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/include/freetype2/config -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include This would just have to be extra information provided, it can't be worked out automatically, though in this case we get it from $ pkg-config --cflags gtk+-2.0 Duncan

Isaac Jones wrote:
Dominic Steinitz
writes: [..] I don't use c2hs myself; is there any pattern to the .h files we might want to preprocess? Any way to derive it from the sources or the module names? I'm not sure how better to support the kind of thing you need.
Explicit specification of .h files on the command line is mainly supported for backward compatibility with old versions of c2hs. The suggested way of handling this with the current c2hs is to have a "#include" in the .chs file. (This does *not* require to run cpp over the .chs file. c2hs understands and interprets cpp directives directly.) It would be nice if future versions of Cabal could directly support c2hs instead of requiring explicit setting of "hookedPreProcessors". If I can help with this, let me know. In the long run, I want to change c2hs' build system over to Cabal, too. Manuel

Manuel M T Chakravarty
Isaac Jones wrote:
Dominic Steinitz
writes: [..] I don't use c2hs myself; is there any pattern to the .h files we might want to preprocess? Any way to derive it from the sources or the module names? I'm not sure how better to support the kind of thing you need. Explicit specification of .h files on the command line is mainly supported for backward compatibility with old versions of c2hs. The suggested way of handling this with the current c2hs is to have a "#include" in the .chs file. (This does *not* require to run cpp over the .chs file. c2hs understands and interprets cpp directives directly.)
Thanks for the info :)
It would be nice if future versions of Cabal could directly support c2hs instead of requiring explicit setting of "hookedPreProcessors". If I can help with this, let me know. In the long run, I want to change c2hs' build system over to Cabal, too.
Cabal does support c2hs directly, except that there's a slight bug (fixed in HEAD) where there's a space at the front of generated files. Using hookedPreProcessors to over-ride the built-in behavior is a workaround for this bug. peace, isaac
participants (4)
-
Dominic Steinitz
-
Duncan Coutts
-
Isaac Jones
-
Manuel M T Chakravarty