
On Mon, 2009-04-27 at 19:03 +0200, Sven Panne wrote:
Am Montag, 27. April 2009 00:11:20 schrieb Duncan Coutts:
On Sun, 2009-04-26 at 19:03 +0200, Sven Panne wrote: [...]
* How to link programs using OpenGL
This is because the GL libs are called different names on different platforms right? But they're consistent within each platform, it's just Windows vs everyone else isn't it?
How about:
if os(windows) extra-libraries: gl32 else extra-libraries: GL
As usual, things are always a bit trickier than they appear initially: On non- Windows systems it is not always sufficient to link against libGL alone, sometimes you'll have to link against several X11 libs, too. I am not sure if this is still a widespread problem, but in the past it was.
Right. It's still possible to use custom code in Setup.hs to test these kinds of things. It's a bit less easy however.
Hopefully most *nices get their dynamic library dependencies right nowadays... :-P Windows is, as always, a special beast, especially when you take Cygwin into account: On Cygwin you can either build against the native OpenGL or against Cygwin's X11 OpenGL. This can be configure via --without-x. How can we do this in .cabal files? And MacOS had some peculiarities which I can't fully remember anymore, too.
I didn't know that there was any working GHC for Cygwin. Or do you mean building a non-cygwin lib but under the cygwin shell?
* The Haskell types corresponding to the OpenGL types
Does hsc2hs #type not help us with this? [...]
I am not sure, because I haven't had a look at hsc2hs for a long time, and at the beginning of the OpenGL binding there were no such tools, not even the FFI in its current form. Perhaps I'll have a look at this, but to make this work, I am sure that we'll have to solve the next item:
* To do the former: How to find the OpenGL C headers
What's needed here? Are they not in standard locations? Cabal has support for users to specify non-standard locations.
What is a "standard location" for headers on Windows? There is no such concept.
Right, there's just the includes that come with ghc's bundled version of mingw. Cabal knows how to find them because they're listed as an include dir for the rts package I think.
On *nices you look into /usr/include and /usr/local/include, and that's it, unless the user tells you something different. And Apple is always a very creative company, so they decided to put *their* OpenGL headers in a completely different path where no -I flag can help...
But you have some way of finding them right? Even if it's platform dependent. We can do the same in the .cabal file or the Setup.hs. There's also a Cabal flag users can pass to tell us about extra lib and include dirs.
Having access to the OpenGL headers is crucial for finding out which C types are behind OpenGL types like GLint, GLenum, ... The OpenGL spec only specifies minimum requirements for these types and *not* their C mapping.
Absolutely, finding headers is important. Cabal now checks at configure time that all header files and libs listed in the .cabal file can actually be found.
* The library calling convention
This is stdcall on Windows and ccall everywhere else right?
How about:
if os(windows) cpp-options: -DCALLCONV=stdcall else cpp-options: -DCALLCONV=ccall
This should be fine, at least when we solve the Cygwin problem discussed above: The X11 OpenGL libraries on Windows do *not* use stdcall, only the native OpenGL libraries. (The whole calling convention story on Windows really, really sucks, IMHO...) Using CPP for this simple task doesn't look right, but with the current FFI I don't see a way around this, which is a shame. Any ideas/proposals for a FFI change?
One suggestion I've seen is just to improve the ffi pre-processors. The c2hs tool is in a position to discover if the calling convention is stdcall or ccall so it could generate the foreign imports correctly.
* How to load OpenGL extensions
I don't know enough of the details here to comment.
You'll have to know if wglGetProcAddress, NSAddressOfSymbol (+ a bit more code) or some variant of glXGetProcAddress has to be used, plus their necessary headers. This is probably doable via some platform switches in Cabal, too.
A few general remarks:
* Ignoring the (usual) Windows trouble, I like autoconf's approach of testing features instead of relying on extremely fragile platform conditionals. The latter are a constant source of troubles and from a SW engineering point of view, they are a clear step backwards. The "I know my platform" approach which you basically propose reminds me of the xmkmf hell from the last millennium: If X11 didn't know your platform, you had a *lot* of fun getting the platform description right.
Honestly, I've not resolved in my mind which approach is better yet. I can see the advantages of the feature tests over static per-platform configurations. On the other hand, declaring packages dependencies (in as much detail as necessary) has great advantages too in terms of automating package management. I'm still looking for a solution that combines the advantages of both. In practise I've not found that most configure scripts actually do feature based tests. There's some, but half of it degenerates into "if we've not got the OSX framework for this then do that". I mean they just end up doing platform-specific conditionals. In the mean time I expect we get a reasonable solution by moving as far as possible the tests into the .cabal and Setup.hs scripts. That would make building on Windows a good deal less painful and it'll let us see clearly what we can provide in Cabal to simplify the Setup.hs scripts.
* We can go this autoconf-free route, but this is a part of my bindings which I definitely won't maintain in full time. I'll be happy to review and accept patches, but making things work on Windows, Cygwin, Linux, *BSD, MacOS X, ... is a lot of work, which is a fact I have painfully learned in the past few years. The autoconf code may be ugly, but the tons of platform differences are ugly, to. I want to work on the binding itself mainly, not on the build system, which currently works. To repeat myself: Patches are happily accepted, but I propose incremental changes and heavy testing on various platforms.
* Most of the tasks my autoconf scripts perform are not specific to OpenGL at all. I guess that most bindings for non-trivial C libraries face the same challenges (Where are my libs? Where are my headers? What are my types?) Having good Cabal support for these would be very nice.
Cabal does now support the common simple case of checking that libs and headers are found (when they're declared in the .cabal file). The types one is probably better dealt with by an FFI preprocessor or possibly just using the FFI libs directly (sizeOf function), but perhaps could be done with help from Cabal. Anyway, so that's why I'd like us to look in detail at what features we need in Cabal to let us switch most packages from using ./configure scripts to using Setup.hs scripts. Duncan