Re: [Haskell-cafe] Win32 Open GL / Glut Applications

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. <RANT> Just a little warning: my instructions could be wrong in some places. Normally, in order to verify my instructions, I would uninstall everything, start from scratch, follow my instructions step by step, and verify that they work. Unfortunately: * I have low confidence in the accuracy of the following instructions. * I have only one machine. * I went through lots of frustration to get freeglut to work with GHCi. * I am not willing to risk breaking my current installation. * I do not know of any easy way to preserve my current installation and still start over from scratch to test my instuctions. </RANT> If my instructions are wrong, then please let me know, and I might attempt to fix it. Although I just don't understand why freeglut, the Haskell GLUT library, and GHCi won't work together in the first place. Here's what I would have to do if I were starting from scratch: 7-Zip http://www.7-zip.org/ This is an open source file archiver for Windows that can handle *.gz and *.bz2 files. Download the Windows version and install it. GHC 6.6.1 http://haskell.org/ghc/download_ghc_661.html#windows This is the version of GHC that I'm using. Download and install it. MinGW/MSYS Download all three files, then install them in the order I have listed them. Note: MinGW and MSYS need to "live" in different directories. http://sourceforge.net/project/showfiles.php?group_id=2435 Automated MinGW installer MinGW-5.1.3.exe ** When you run the installer, it will download several more files for you. MSYS: Minimal System MSYS-1.0.10.exe http://sourceforge.net/project/showfiles.php?group_id=2435&package_id=67879 MSYS Supplementary Tools msysDTK-1.0.1.exe ** Scroll down to find "Current Release: msysDTK-1.0.1" and expand this tab. Select "msysDTK-1.0.1.exe" zlib-1.2.3 http://www.zlib.net/ The links for "zlib source code" are about halfway down the page. After downloading, the process (IIRC) is 1. Unzip the source code. 2. Start MSYS and cd to the source-code directory. 3. Execute "./configure" 4. Execute "make" 5. Execute "make install" I don't remember having any problems with zlib. cURL-7.16.4 http://curl.haxx.se/download.html Note: It appears that cURL just had a minor revision on Sept 13. I guess you can just try the latest version and see of things work. IIRC, the process is exactly the same as the zlib install process, and I didn't have any problems here either. darcs-1.0.9 http://darcs.net/darcs-1.0.9.tar.gz Dependencies that you'll need: cURL and zlib :-) Your darcs installation will have some holes, for example it won't support SSL because we didn't satisfy the SSL dependency. IIRC, the process here is 1. Unzip the source code. 2. Start MSYS and cd to the source-code directory. 3. Execute "autoconf" 4. Execute "./configure" 5. Execute "make" 6. Execute "make install" Freeglut-2.4.0 http://freeglut.sourceforge.net/index.php#download Here's where the hackery starts. 1. Download the Freeglut source code and unzip it. 2. Start MSYS and cd to the source-code directory. 3. Execute "./configure" 4. Download this custom makefile and put in in the "./src" directory. http://hpaste.org/2841 5. Download this custom def file and put in in the "./src" directory. http://hpaste.org/2842 6. Cd to the "./src" directory and then execute "make". 7. Copy the "freeglut.dll" to GHC's bin directory (ghc-6.6.1/bin). 8. Copy the *.h files from "freeglut-2.4.0/include/GL" to "ghc-6.6.1/include/mingw/GL". Note that "glut.h" will be overwritten. GLUT-2.1.1 You need to use darcs to download GLUT-2.1.1. 1. Start MSYS, create a directory for the GLUT source code, and cd to it. 2. Execute "darcs get http://darcs.haskell.org/libraries/GLUT/" and wait a while. 3. Cd to your new source directory. 4. Execute "autoreconf" and wait a while. 5. Modify "GLUT.cabal" as follows: Locate the line start starts with "build-depends:" and remove the dependencies "array" and "containers" 5. Execute "runghc Setup.hs configure" and wait. 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. 8. Execute "runghc Setup.hs build" and wait. 9. Execute "ghc-pkc unregister GLUT". This unregisters the existing GLUT haskell library. Also, search through GHC's directories, locate any glut library files (*.a, *.o, *.hi) that are in there and remove them. You are deleting the existing GLUT that came with GHC 6.6.1 in order to replace it with Freeglut. 10. Execute "runghc Setup.hs install". 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"] >>. 12. At this point, you should be able to start GHCi, load an example that depends on freeglut, and run it from GHCi, without getting any crashes or weird errors. 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. Good Luck! -- Ron

Oops, one slight omission: 4. Download this custom makefile and put in in the "./src" directory. http://hpaste.org/2841 ** Call this file "Makefile", with no extension. 5. Download this custom def file and put in in the "./src" directory. http://hpaste.org/2842 ** Call this file "freeglut.def". -- Ron

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... :-(
[...] 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.
[...] 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-c7910dd98302946c671cf6... 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.
[...] 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?
{...] 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?
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? Cheers, S.

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... :-(
[...] 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
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
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
And frustrating too. :-) properly, the that.The 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:
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
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
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
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
http://wiki.darcs.net/DarcsWiki/CategoryBinaries#head-c7910dd98302946c671cf6... Ooo, Thank you! ;-) this is this. there will 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?
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
By this time, I have bypassed the correct installation of 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

Wow, what an interesting bunch of reads. I still haven't tried the options
yet as I dont work with windows too much. What was the consensus? on the
steps to follow. I will try finding a freeglut dll and then changing the
name to opengl32.dll and see if that works.
On 9/23/07, Ronald Guida
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-c7910dd98302946c671cf6...
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
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (3)
-
John Wicket
-
Ronald Guida
-
Sven Panne