Static linking GLFW with D

Using GLFW
2005-07-01
2012-11-08
  • Nobody/Anonymous

    How do I go about compiling a static link library of GLFW for use with D? I prefer not having to supply DLLs with my programs, and I'd like some form of a "glfw.lib" which I could link directly to my executables.

    I tried hacking a makefile in the \lib\win32 directory, and after a bit of messing about (converting the makefile to use the Digitalmars C compiler and linker, fixing one cast error in win32_enable.c) I did get a glfw.lib. It linked and compiled fine with the C examples (boing ran fine), but if I try to link the same library with the D examples I get undefined symbol errors for all the GLFW functions. The glfwdll.lib naturally resolves these, but then I need the .dll to run the program and I'm back to step one.

    What am I doing wrong? Have others got GLFW to statically link with their D files?

    P.S: if possible, can we get a pre-built GLFW static link library as well as a DLL? It'd make at least my life a lot easier...

     
    • Anonymous - 2005-07-01

      I haven't tried using the dmc compiler recently with glfw, but I think I succeeded sometime last year with a static lib. I prefer the dll over the static lib, though.

      Anyway to fix the problem, look at glfw.h and notice that a __DMC__ (or whatever the dmc compiler macro is) specific macro is not present. This means that lines 150-153 (glfw 2.5) take effect in that header. GLFWAPIENTRY, GLFWAPI, GLFWCALL will have empty defintions for dmc when you compile the static library. That means that all public glfw functions are given default calling conventions (extern "C"). The D import module (glfw.d) expects to see __stdcall for win32 platforms: notice the extern(Windows). Thus, as is, your D glfw function declarations will not match the glfw.lib symbol names.

      There are two ways of fixing this, I believe:

      (1) The sort of long way

      Try fixing this by either adding a __DMC__ macro section to the glfw.h header file that explicitly defines __stdcall to the appropriate GLFWxxxx macro.

      (2) The short way

      Don't touch glfw.h, compile glfw as a static lib as before, and try changing the d import module to declare the public functions extern(C) instead of the default extern(Windows) (see the top of glfw.d).

      The reason for doing this is because the glfw library defaults to extern "C" for all functions in glfw.h for undefined compilers. And since DMC isn't defined and the GLFWxxxx macros are empty (as you compiled it for dmc), then no function is defined __stdcall which is the equivalent of D's extern(Windows).

      Hopefully this helps.

      Also, since you use D, have a look at the Derelict project at www.dsource.org. It includes a glfw import also... although it's for the dynamic version. Currently, it's at version 2.4.2. I need to update it to 2.5 sometime soon.

      -JJR

      - JJR

       
      • Nobody/Anonymous

        Thanks much, I used your method (2) (didn't bother to try method (1) since you said it was long ;-)) and it worked - of course, I also had to use extern (C) instead of extern (Windows) for callback functions in the actual source files to make them compile, since the callback function typedefs were now under extern(C).

        I knew of Derelict beforehand... I actually tried DerelictGLFW before plain GLFW, presuming that, being made for D from the start, it would be easier to use, and I wouldn't have to worry about extern or similar problems like I may have to (and now I know that I do have to ;-)) with 'vanilla' GLFW. But two reasons turned me back to plain old GLFW:

        First, as you say, they also use the DLL and not the static library. They apply their 'dynamic loader' system which allows them to dynamically load DLLs as needed, and thus they use the GLFW DLL as well. I don't find this a necessity for my own projects, which only include libraries if they are practically certain to be used anyhow.

        Second, I found that that system necessitates too much extra code for comfort, especially since I wouldn't use the whole system but would still have needed to add the callback functions (it appeared so at least; I didn't go as far as trying to code something of my own using DerelictGLFW).

        Besides, I felt it would be just another extra library which I don't need - after all, if I want to use only GLFW, why get Derelict on top? :-)

        Anyhoo, you solved my problem, thanks again for that.