Search code examples
windowsopenglghci

How do i get GHCi to load Opengl packages?


I can successfully build executables that link against OpenGL using GHC, however I cannot get the package to load into GHCi. This is definitely a regression for me because it works on 32-bit GHC (at least the version I upgraded from). I do not think the GHC version matters, just the fact that I am using the 64-bit GHC system.

On the recommendation of the maintainer I explicitly brought the correct 64-bit version of opengl32 into GHCi successfully. It seems to be an issue higher up the stream.

Here is the output that is relevant. The verbose output is unfortunately just as specific. The function wglGetProcAddress is used to find where the opengl api hooks are in the dll.

$ ghcii.sh  -package OpenGL   
GHCi, version 7.6.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package OpenGLRaw-1.2.0.0 ... linking ... ghc.exe: unable to load 
package `OpenGLRaw-1.2.0.0'
ghc.exe: C:\...\cabal\OpenGLRaw-1.2.0.0\ghc-7.6.1\HSOpenGLRaw-1.2.0.0.o: 
unknown symbol `__imp_wglGetProcAddress'

Solution

  • It's been some time since I've dabbled on that level of Haskell development. But it looks similar enough to a standard linking problem.

    I can give you an answer on why it happens, but at the moment am at a loss how to resolve it short of fixing the problem upstream.

    The function wglGetProcAddress is found in opengl32.dll. So your HSOpenGLRaw seems not to be properly linked against that, hence the failure to locate the symbol.

    If this happened in a *nix environment a simple solution would be to LD_PRELOAD libGL.so. However on Windows loading a module into a process doesn't make its symbols automatically visible to the rest of the process, so that wouldn't work there.

    This also explains why it works for standalone binaries. Those are linked outside of runtime. Thus extra libraries can be passed to the linker which will resolve the missing dependencies.