-2

I'm trying to compile one of these mixes of X11 + OpenGL, but I'm not having luck with the compiler. In particular, I get:

  undefined symbol: glXMakeCurrent

I have tried

   -lX11 -lGLU -lGL -lXext

as arguments to the linker, and some permutations of them, with no luck so far.

I'm running Ubuntu 12.04, and I have installed all the development packages related to opengl that I had a fuzzy idea could be related. I'm also developing in C++, something that could cause problems if the opengl headers are not prepared for it... but they are right?

I even looked for the symbol explicitly with an fgrep in /usr/lib/x86_64-linux-gnu/, but it is not there, and furthermore, `nm' says that there are no symbols.

So, what's the correct way of linking with glx?

EDIT: It is linking problem, the error is produced when python tries to load the compiled (and incorrectly linked) module. Not at compilation time.

EDIT: Here is the compilation log

    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
    g++ -o build/debug/objects/alve/layouter/flowing_data.os -c -std=c++0x -g -I/usr     /include/python2.7 -fPIC -I/opt/cairo_new/include/cairo/ -I/opt/boost_1_48_0/include -DMIC_RT_SPEED_BACKS -Icsrc csrc/alve/layouter/flowing_data.cpp
    g++ -o build/debug/objects/alve/layouter/liblayouter.so -L/opt/cairo_new/lib -L/opt/boost_1_48_0/lib -shared build/debug/objects/alve/layouter/flowing_data.os build/debug/objects/alve/layouter/show_network.os -Lbuild/debug/lib -Llibdeps
    Install file: "build/debug/objects/alve/layouter/liblayouter.so" as "build/debug/lib/liblayouter.so"
    g++ -o build/debug/objects/alve/layouter/liblayouter_mod.so -L/opt/cairo_new/lib -L/opt/boost_1_48_0/lib -shared build/debug/objects/alve/layouter/module.os  Lbuild/debug/lib -Llibdeps -lboost_python build/debug/objects/alve/layouter/liblayouter.so -lcairo -lX11 -lGL -lGLU -lXext
    scons: done building targets.

and here is how the function is called:

glXMakeCurrent (dpy, win, ctx);
dsign
  • 12,340
  • 6
  • 59
  • 82
  • This question lacks vital information, like that clearly stating that this is for a Python import module. Required information: Source code outline, build configuration (Makefile, or similar), **compiler** flags and full set of linker flags. – datenwolf Oct 23 '12 at 10:50
  • @datenwolf My question is "what's the correct way of linking against glx in linux"... if the answer requires the entire world as an argument... well I would have tagged it "Haskell" in that case. – dsign Oct 23 '12 at 10:57
  • 1
    The correct way to link GLX is by adding libGL.so to your set of linked libraries – what you already did – as described in the Linux OpenGL ABI (to be found on the OpenGL website). However of the compiled binary is dynamically linked into another program, special precautions must be taken. Which those are depend on the target program. – datenwolf Oct 23 '12 at 12:42
  • @datenwolf As you can see, the target program is a dynamic module for python. And the libraries are added in the last compilation step. I fixed it by adding the libraries also for the linking of the intermediate shared object, otherwise the linker just discards them. – dsign Oct 23 '12 at 12:55

2 Answers2

2

The message "undefined symbol" indicates that it's not a linker, but a compilation unit problem: The compiler does not know the symbol glXMakeCurrent because it has been neither declared, nor defined, but you use it.

Probably the GLX header has not been included.

Add

#include <GL/glx.h>

As it turns out OPs problem was related to the fact, that the build consisted of cascading shared objects forming a Python module. One shared object implements the actual OpenGL operations, while the other does the interfacing to the Python interpreter.

Now shared objects (.so) are fully qualified ELF binaries themself, each with their own import and export symbol table. A shared object can be configured to expose all the symbols of other shared object it links to. However a shared object will not see any symbols of the compilation units they're linked into (if you think about it, this is to be expected, as a shared object can not and should not make any assumptions about the environment it's going to be linked into).

Hence, when compiling and linking multiple shared object in a larger build it's important to individually link each shared object to any libraries it will need at runtime.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • It is a linker problem. Compilation runs flawlessly, even linking, as am producing an extension module for python... the problem comes when dyn-linking the module. – dsign Oct 23 '12 at 09:58
  • Plus, my g++ usually says "'something' was not declared in this scope" for undeclared symbols. – dsign Oct 23 '12 at 10:04
  • @dsign: This is vital information your original question was missing. You neither told us that you were trying to create a Python module, nor that the error happens when trying to load the module. Python does load modules through dlopen and certain things to work very differently in that circumstances. Still your question misses important information, like the basic outline of your modules code, build configuration, etc. – datenwolf Oct 23 '12 at 10:49
0

As @datenwolf ways, special precautions are needed for linking. Which are them is a mystery for me, but using ldd helps. So basically what I did was to use ldd in both the final and the intermediate shared objects. Despite the command line arguments, my library didn't get linked with libGL and its dependencies until I also included the '-lGL -lGLU -lX11' in the intermediate step (production of 'liblayouter.so').

dsign
  • 12,340
  • 6
  • 59
  • 82
  • Actually this is not a surprise, as it is liblayouter.so that apparently quires the functionality of libGL.so. Hence it is this very .so that must contain the dynamic linkage entry. The shared object liblayouter_mod.so in turn does dynamically link against liblayouter.so. Now if you add -lGL to the _mod.so only the _mod.so actually sees libGL.so whereas liblayouter.so is on the dry. Also keep in mind that the _mod.so does require liblayouter.so in it's dynamic linker path. – datenwolf Oct 23 '12 at 16:17
  • @datenwolf Thanks for your help. I would like to close this question. Can you put your last comment as your answer so that I can accept it? – dsign Oct 23 '12 at 16:37