Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't link OpenCL on Windows with GHC

I'm trying to get the OpenCLRaw bindings to a point where I can use them on windows. I've forked the the OpenCLRaw repo on github so I can make modifications as needed. My branch is here: https://github.com/dagit/OpenCLRaw

I've been mostly working out of my "FunPtr" branch.

The issue I'm having is this: I installed AMD's OpenCL SDK, converted their Visual Studio specific .lib file to a file that gcc can handle (.a file), but ghc can't seem to link with it. I get undefined symbols for everything I use in the OpenCL API.

I was able to build a "trivial" C program and link it using the .a file that I generated and gcc from mingw (not from the Haskell install). I'm using the latest windows release of the Haskell platform.

These are the steps I used for generating the .a file: http://forums.amd.com/forum/messageview.cfm?catid=390&threadid=138890

I used the commands in the example script (e.g., gendef and dlltool). I've tried to use 32bit everything as much as possible, as I know that GHC will want everything to be 32bit, so I don't think it's a 32bit vs. 64bit issue.

Does anyone know if there is something different about invoking gcc under ghc instead of the gcc that I get from mingw?

I've also played with the ghc command line (I used cabal-dev --verbose=3 to inspect the command line) and I'm still unable to massage it into a working state.

Any help would be appreciated!

like image 647
Jason Dagit Avatar asked Sep 12 '11 17:09

Jason Dagit


1 Answers

OpenCL uses the stdcall convention, but OpenCLRaw is using ccall. This creates several issues. The main one being that the linker wants the function name symbols to end in @NN where NN depends on the function.

As it turns out, the correct way to generate libOpenCL.a is as follows (from a mingw shell):

cp /c/Windows/System32/OpenCL.dll .
gendef OpenCL.dll
dlltool -l libOpenCL.a -d OpenCL.def -k -A

This will generate libOpenCL.a that ghc can correctly use for linking, but only if OpenCLRaw is modified to use stdcall instead of ccall.

Now that I understand the problem I can fix the OpenCLRaw bindings to do the right thing on Windows.

When I used pexports instead of gendef, I was able to remove the @NN from the symbol names, but then the resulting program started to segfault. This is because the symbol was found but the calling convention was incorrect, probably leading to corrupted stacks.

The main lesson for me is that your FFI binding must match your C library's calling convention.

like image 194
Jason Dagit Avatar answered Oct 20 '22 09:10

Jason Dagit