[Haskell-cafe] Win32 Open GL / Glut Applications

Ronald Guida ronguida at mindspring.com
Sun Sep 23 17:50:40 EDT 2007


Sven Panne wrote:
 > On Friday 21 September 2007 20:19, Ronald Guida wrote:
 >> John Wicket wrote:
 >>  > yea, that is probably what I need.  Can you post in a 
step-by-step way.
 >>
 >> Here is a set of instructions for what I had to do to get FreeGLUT
 >> working with GHCi [...].
 >
 > Oh dear, a long a sad story... :-(

And frustrating too.  :-)

 >> [...]  Although I just don't understand why freeglut, the
 >> Haskell GLUT library, and GHCi won't work together in the first place.
 >
 > That statement is not correct, they *do* work together. The problem 
you are
 > experiencing is that the GLUT version used to build the GHC 
installer/binary
 > distro is obviously not freeglut, but "classic" GLUT. As long as you 
only
 > use "classic" GLUT features, this is OK. Things get really hairy when 
you
 > want to use freeglut-only features and still have a GHC installer/binary
 > distro which is guaranteed to run with "classic" GLUT as well (with
 > restricted features in the latter case, of course). To do this 
properly, the
 > GLUT package has to resolve freeglut-only API entries dynamically, but
 > glutGetProcAddress is not contained in lots of GLUT DLLs out in the wild
 > (it's in GLUT API version 5 plus freeglut). This is really a pity and 
a big
 > design flaw in GLUT IMHO, but there is not much one can do about 
that.The
 > only thing left is to load the GLUT/freeglut dynamic library,
 > well, "dynamically" and resolve the freeglut API entries by hand. 
Doing this
 > is not hard, but a little bit tricky to get right portably: Use 
dlopen/dlsym
 > on most *nices, LoadLibrary/GetProcAddress on Windoze, something else 
on Mac
 > OS, take care of possible leading underscores, etc. etc. I really 
wanted to
 > avoid doing this, but it looks like there is no way around it. Given the
 > current time frame for the GHC 6.8.1 release, I don't think that it is
 > feasible to get this into that release, because I would need feedback 
from
 > lots of platforms to be sure things work.

In fact, when I compiled freeglut with MSVC, it compiled successfully
"out of the box".  When I tried to use my new freeglut.dll with GHCi,
I got linker errors all over the place and I eventually discovered
that the problem involves leading underscores.

 >> [...] darcs-1.0.9
 >>   http://darcs.net/darcs-1.0.9.tar.gz [...]
 >
 > There are darcs binaries for Windows, so there is no need to build it 
and the
 > libraries it needs:
 >
 > 
http://wiki.darcs.net/DarcsWiki/CategoryBinaries#head-c7910dd98302946c671cf63cb62712589b392074

Ooo, Thank you!  ;-)

 > Furthermore, darcs itself is not needed for what you want to do.
 >
 >> [...] Freeglut-2.4.0
 >>   http://freeglut.sourceforge.net/index.php#download [...]
 >
 > The freeglut project currently doesn't provide prebuilt binaries, so 
this is
 > hardly the GLUT package's fault. ;-) Furthermore, the official way to 
build
 > the project on Windows is via MSVC, and there are projects files for 
this.
 > Building a DLL via MinGW/MSYS would be nice, too, so perhaps you 
could post
 > your patches in the freeglut-developer mailing list. I think that 
there will
 > be a new freeglut release soon, perhaps I can push people to make at 
least a
 > simple ZIP file with the binaries for Windows available on the 
project pages.
 >
 >> GLUT-2.1.1
 >>   You need to use darcs to download GLUT-2.1.1.
 >> [...]
 >>        Locate the line start starts with "build-depends:" and remove
 >>        the dependencies "array" and "containers"
 >
 > Now you enter the great world of Cabal versionits and the Big Library 
Splitup
 > (tm). ;-) If you want to use a bleeding edge version of GLUT, you need a
 > bleeding edge version of GHC and the libraries coming with it. A 
released
 > version is available via hackage.haskell.org.

Rumor: Version-itis and the big library splitup are going to break
everyone's existing code!  :-O

 >>   [...] 6. Modify "GLUT-2.1.1/Graphics/UI/GLUT/Extensions.hs" as 
follows:
 >>
 >>        Look at the last two lines:
 >>
 >> foreign import ccall unsafe "hs_GLUT_getProcAddress" 
hs_GLUT_getProcAddress
 >>
 >>    :: CString -> IO (FunPtr a)
 >>
 >>        Change "hs_GLUT_getProcAddress" to "glutGetProcAddress"
 >>
 >>   7. Modify "GLUT-2.1.1/cbits/HsGLUT.c" as follows:
 >>
 >>        Look for "void* hs_GLUT_getProcAddress(char *procName)" and
 >>        remove the whole function.
 >
 > Huh? If you *really* compile against the freeglut header, these steps 
are
 > unnecessary. What is the reason for this change?

The reason for this change is that I had reached the point where I had
one remaining linker error.  I found that hs_GLUT_getProcAddress is a
stub that calls the real glutGetProcAddress, and I figured out that
this call to the real glutGetProcAddress was refusing to link.  I made
the determination that (1) the stub is there to fix a broken
glutGetProcAddress, and (2) mine isn't broken.  Therefore, instead of
trying to find the cause of the linker error, I decided to avoid the
error entirely by removing the stub and calling directly to the real
thing.

 >> {...]
 >>   11. In GHC's directory, there is a file named "package.conf".  This
 >>       file contains one extremely long line.  You need to find an
 >>       editor that will let you insert some text into this line without
 >>       introducing any line breaks.  Emacs can do this.
 >>
 >>       You need to locate the text << pkgName = "GLUT" >> and then you
 >>       need to locate << hsLibraries = ["HSGLUT-2.1.1"] >> to the right
 >>       of there.  The very next thing to the right of "hsLibraries"
 >>       should be << extraLibraries = [] >>.  You need to change it to
 >>       << extraLibraries = ["freeglut"] >>.
 >
 > This is unnecessary if you install the freeglut DLL correctly. What 
is the
 > output of "ghc-pkg describe GLUT" before this modification?

By this time, I have bypassed the correct installation of freeglut.

 >>   13. If you want to /compile/ with GHCi, then you'll need to copy the
 >>       freeglut.dll file into the same directory as your newly-compiled
 >>       program.exe file.  I haven't tried static linking yet; that
 >>       would require recompiling freeglut as a static library instead
 >>       of a DLL.
 >
 > The "traditional" way is to put the DLL as "glut32.dll" into your
 > WINDOWS/system32, just next to opengl32.dll. :-P I don't know what the
 > Vista-approved way of doing this is, and probably the freeglut 
project needs
 > an installer. Any volunteers?

The issue here is DLL Hell.  I now have two versions of the freeglut
DLL.  One of them came from MSVC and the other came from my hacking.
Neither version can be substituted for the other.  Putting the DLL
file into the same directory as the EXE file appears to guarantee that
the EXE picks it up.  Static linking would avoid the problem entirely.

I just wish GHCi would link with the MSVC version of the freeglut DLL.

What I really wish for, are pre-compiled versions of each piece that
work together and a fully automated installer that select all the
right versions of everything and put all the right pieces in all the
right places.

The best part of all is this: I went through so much trouble trying to
get freeglut, Haskell-GLUT, and GHCi to play together and run some
examples, that once I finally got it working, I ended up deciding
/not/ to look at graphics programming for a while.

-- Ron



More information about the Haskell-Cafe mailing list