ddynamic-linkingopengl-3gdcderelict3

Linking to DerelictGL3 with GDC


TL;DR:

How do I get from having the source for DerelictGL3 et al, to linking to it, with GDC?

Detailed complaints:

I have a small program written in D. (http://dlang.org)

module controller;

import std.stdio;
import std.conv;
import std.exception;
import derelict.opengl3.gl3;
import derelict.glfw3.glfw3;

void main()
{
    DerelictGL3.load();
    DerelictGLFW3.load();

    if(!glfwInit())
        throw new Exception("Failure");
    scope(exit) glfwTerminate();
}

I'm trying to build this program with the following command. (I'm on linux.)

gdc -o "${BLD}controller" \
    "/home/user/Source/d/controller.d" \
    "-I/home/user/Source/DerelictOrg/DerelictUtil/source/" \
    "-I/home/user/Source/DerelictOrg/DerelictGL3/source/" \
    "-I/home/user/Source/DerelictOrg/DerelictGLFW3/source/" \
    -I/usr/include/d2 \
    -L -lDerelictUtil \
    -L -lDerelictGL3 \
    -L -lDerelictGLFW3 \
    -L -ldl

I get the following error messages.

controller.d:(.text+0x3b): undefined reference to 
  `_D8derelict7opengl33gl311DerelictGL3C8derelict7opengl33gl317DerelictGL3Loader'
controller.d:(.text+0x4c): undefined reference to 
  `_D8derelict7opengl33gl311DerelictGL3C8derelict7opengl33gl317DerelictGL3Loader'
controller.d:(.text+0x58): undefined reference to 
  `_D8derelict5glfw35glfw313DerelictGLFW3C8derelict5glfw35glfw319DerelictGLFW3Loader'
controller.d:(.text+0x69): undefined reference to 
  `_D8derelict5glfw35glfw313DerelictGLFW3C8derelict5glfw35glfw319DerelictGLFW3Loader'
controller.d:(.text+0x75): undefined reference to 
  `_D8derelict5glfw35glfw38glfwInitPUNbZi'
controller.d:(.text+0xf7): undefined reference to 
  `_D8derelict5glfw35glfw313glfwTerminatePUNbZv'
/tmp/ccTqE9NN.o:(.data+0x28): undefined reference to 
  `_D8derelict7opengl33gl312__ModuleInfoZ'
/tmp/ccTqE9NN.o:(.data+0x30): undefined reference to 
  `_D8derelict5glfw35glfw312__ModuleInfoZ'
collect2: error: ld returned 1 exit status

I'm fairly certain that none of the arguments I'm passing to GDC are correct, past the name of my source file. The behavior is identical if I comment out all the -L lines. If I comment out the -I lines, I get the following.

controller.d:6: error: module gl3 is in file 'derelict/opengl3/gl3.d' 
    which cannot be read

However, I expect that could be resolved with a well placed library.

How do I get from having the source for DerelictGL3 et al, to linking to it, with GDC?

Edit: I'm confident I've installed libDerelictGL3.a, libDerelictGLFW3.a, and libDerelictUtil.a in /usr/bin/.

More thoughts: I'm really quite confused as to why I need to compile against the source. This isn't C++ and there are no header files. When I forego the -I lines, the compiler doesn't know how to open the gl3 module. Shouldn't it just infer that the functions I used exist, and then have linker errors if/when it cannot find them? Given as I have the libraries compiled and in the search path, why can't GDC figure the rest out?

More thoughts: I recently found Can't link GLFW3: undefined references In that case, the OP found that they needed their libraries in .so form, rather than .a form, since they were attempting a dynamic link. I'm currently investigating that.

Another piece of the puzzle: I've changed the relevant portion of my gdc call to

-I/usr/include/d2 \
-L -ldl \
-L/usr/bin \
-lDerelictUtil \
-lDerelictGL3 \
-lDerelictGLFW3

Now, rather than having trouble linking to Derelict, I appear to be having trouble linking to the _d_runtime itself.

Output is hundreds of lines similar to these:

/usr/bin/libDerelictGL3.a(libDerelictGL3.o): In function
  `_D3std5array18__T8AppenderTAPxaZ8Appender13ensureAddableMFNaNbNfmZv':
/home/user/Source/ldc-developers/ldc/runtime/phobos/std/array.d:2231:
  undefined reference to `_d_allocmemoryT'

Thus, I believe that my problem is that _d_runtime (forgive me if that's the wrong name) is somewhere other than /usr/bin, and when I override my -L path to /usr/bin (since that's where I put the libs) I have problems finding it. Either that, or I simply installed D wrong in the first place. But in either case, it is actually finding libDerelictGL3.a in the aforementioned example! =)


Solution

  • Edit: I suppose I left out the actual line to build Derelict with gdc.

    dub --compiler=gdc
    

    I executed this in the source directory of each of the derelict packages, and copied the contents of lib/ to /usr/bin.


    I've figured it out. Time for a thorough post-mordem "for the next guy".

    I started this project some time ago, and I forgot that I had started off using ldc, an llvm based D compiler. For some reason, I symlinked /usr/bin/dmd2 to a local build of ldmd2, sitting as a fresh binary in a source directory. My build of the various DerelictOrg projects used dub, which then used ldmd2, and thus a local, probably forked, copy of the d runtime.

    Basically, the rest of the project was setup correctly. For the sake of the next guy, here's what my script ended up as:

    gdc -o "/home/user/Build/controller" \
      "/home/user/Source/d/controller.d" \
      -I/usr/include/d \
      "-I/home/user/Source/DerelictOrg/DerelictUtil/source/" \
      "-I/home/user/Source/DerelictOrg/DerelictGL3/source/" \
      "-I/home/user/Source/DerelictOrg/DerelictGLFW3/source/" \
      -lDerelictUtil \
      -lDerelictGL3 \
      -lDerelictGLFW3 \
      -ldl
    

    Humorously enough, the ldc vs gdc mistake made it all the way to the log I posted here. Too bad I didn't read my own log closely enough.