recent changes to hsc2hs break wrapping c++

Recently a change was made to hsc2hs to fix this ticket: http://hackage.haskell.org/trac/ghc/ticket/2897 Unfortunately, the result is I (apparently) can't use it now. Here's how that happens: The change was to remove the dependency on HsFFI.h. However, the solution is to create a little wrapper .c file that includes wrappers around various stdio functions like fputs(). This relies on C allowing implicit casts from void* to e.g. FILE*, and is also happy to let you use undeclared functions. g++ rejects that code. And since I am calling into C++ (via a 'extern "C" { ... }' wrapper) I wind up including C++ headers that contain the structs I want hsc2hs to calculate offsets for. Of course one solution is to use C as hsc2hs expects, but it would be awkward to split my (largish) c++ program's headers into C compatible and C++ only. So meanwhile I've reverted back to an older version of hsc2hs that includes HsFFI.h. Working with c++ headers was maybe not in the original design for hsc2hs, but it's a very useful feature nonetheless. WRT HsFFI.h and the ticket, I added -I(ghc --print-libdir)/include to my hsc2hs rule a long time ago, and it wasn't very hard to do, though I admit it would have been easier had there been documentation about what to do, or a mandatory flag for the HsFFI.h path. It looks like Duncan suggested that already. Or perhaps there's a better way to wrap C++?

On 02/15/2012 09:59 PM, Evan Laforge wrote:
Unfortunately, the result is I (apparently) can't use it now. Here's how that happens: The change was to remove the dependency on HsFFI.h.
Evan, *if* including HsFFI.h is the only thing you need, you might try to add "-i HsFFI.h" to your hsc2hs rule. The problem still stands because we cannot expect every module author to do the same. Disclaimer: I am in no way expert, what I am saying is a result of layman's investigation and may be far off the mark. Eugene

On Wed, Feb 15, 2012 at 11:17 AM, Eugene Crosser
On 02/15/2012 09:59 PM, Evan Laforge wrote:
Unfortunately, the result is I (apparently) can't use it now. Here's how that happens: The change was to remove the dependency on HsFFI.h.
Evan, *if* including HsFFI.h is the only thing you need, you might try to add "-i HsFFI.h" to your hsc2hs rule.
Well, the main thing is that the C++ compiler chokes on the C stub file created. So as long as it creates and tries to compile that with the compiler given in '-c' then it'll crash. I guess another solution would be a separate '-c' flag for the compiler used for the stub :)
The problem still stands because we cannot expect every module author to do the same.
I think it's not too big a burden since for ghc it's just -I$(ghc --print-libdir)/include, and Duncan makes a good case for requiring it.

On 15/02/2012 19:51, Evan Laforge wrote:
On Wed, Feb 15, 2012 at 11:17 AM, Eugene Crosser
wrote: On 02/15/2012 09:59 PM, Evan Laforge wrote:
Unfortunately, the result is I (apparently) can't use it now. Here's how that happens: The change was to remove the dependency on HsFFI.h.
Evan, *if* including HsFFI.h is the only thing you need, you might try to add "-i HsFFI.h" to your hsc2hs rule.
Well, the main thing is that the C++ compiler chokes on the C stub file created. So as long as it creates and tries to compile that with the compiler given in '-c' then it'll crash. I guess another solution would be a separate '-c' flag for the compiler used for the stub :)
The problem still stands because we cannot expect every module author to do the same.
I think it's not too big a burden since for ghc it's just -I$(ghc --print-libdir)/include, and Duncan makes a good case for requiring it.
I'm not sure why you're using the C++ compiler from hsc2hs, and I don't think that is guaranteed to work. But maybe we can fix it if there's a legitimate reason to want it. Cheers, Simon

On Thu, Feb 16, 2012 at 4:27 AM, Simon Marlow
I'm not sure why you're using the C++ compiler from hsc2hs, and I don't think that is guaranteed to work. But maybe we can fix it if there's a legitimate reason to want it.
Well, consider if you're writing c++ along with haskell. You can communicate with c++ by passing structs, which are guaranteed to have the layout as c, and call functions wrapped in extern "C" {...}. You can't call class constructors from haskell or anything, but you can create structs to pass in and use directly in c++, which is already quite convenient. But those C structs are going to be defined in C++ headers with other C++ cruft in them that a C compiler is not going to understand. But if you pass -c g++ to hsc2hs then it works just fine to emit the struct offsets. Otherwise, I'm not sure how you'd call C++ from the haskell FFI. Like I said, I guess you'd have to split the C structs into separate headers, or maybe wall off the C++ bits with ifdefs. Actually, I guess the ifdef part wouldn't be *so* bad, at last as far as ifdeffery goes, but it is intrusive on existing headers, which is not going to be possible in all situations. Of course if the C++ API was written without regard to the haskell FFI it is likely to require structs to be constructed with constructors instead of direct pokes, which is beyond the FFI's capabilities. But in the case where it is designed to use plain structs in the haskell-facing bits, it's very convenient how you can just pass -c g++ to earlier versions of hsc2hs and have it just work.

On 18/02/2012 05:22, Evan Laforge wrote:
On Thu, Feb 16, 2012 at 4:27 AM, Simon Marlow
wrote: I'm not sure why you're using the C++ compiler from hsc2hs, and I don't think that is guaranteed to work. But maybe we can fix it if there's a legitimate reason to want it.
Well, consider if you're writing c++ along with haskell. You can communicate with c++ by passing structs, which are guaranteed to have the layout as c, and call functions wrapped in extern "C" {...}. You can't call class constructors from haskell or anything, but you can create structs to pass in and use directly in c++, which is already quite convenient.
But those C structs are going to be defined in C++ headers with other C++ cruft in them that a C compiler is not going to understand. But if you pass -c g++ to hsc2hs then it works just fine to emit the struct offsets.
Otherwise, I'm not sure how you'd call C++ from the haskell FFI. Like I said, I guess you'd have to split the C structs into separate headers, or maybe wall off the C++ bits with ifdefs. Actually, I guess the ifdef part wouldn't be *so* bad, at last as far as ifdeffery goes, but it is intrusive on existing headers, which is not going to be possible in all situations. Of course if the C++ API was written without regard to the haskell FFI it is likely to require structs to be constructed with constructors instead of direct pokes, which is beyond the FFI's capabilities. But in the case where it is designed to use plain structs in the haskell-facing bits, it's very convenient how you can just pass -c g++ to earlier versions of hsc2hs and have it just work.
Ok, I buy that it's useful to be able to do this. I suggest you make a ticket and describe the problem. Is it possible you'd be able to make a patch to fix it too? Cheers, Simon

On Tue, Feb 28, 2012 at 2:16 AM, Simon Marlow
Ok, I buy that it's useful to be able to do this. I suggest you make a ticket and describe the problem. Is it possible you'd be able to make a patch to fix it too?
So I finally got around to taking a look at this. Sorry it's been so long, it's too easy to put things off when you just have to keep using the old version. Anyway, it turns out it's a trivial fix. I created and ticket and added a patch at http://hackage.haskell.org/trac/ghc/ticket/7232
participants (3)
-
Eugene Crosser
-
Evan Laforge
-
Simon Marlow