【问题标题】:Correctly linking GLX library in Ubuntu在 Ubuntu 中正确链接 GLX 库
【发布时间】:2012-10-23 09:33:51
【问题描述】:

我正在尝试编译其中一种 X11 + OpenGL 组合,但我对编译器不满意。特别是,我得到:

  undefined symbol: glXMakeCurrent

我试过了

   -lX11 -lGLU -lGL -lXext

作为链接器的参数,以及它们的一些排列,到目前为止还没有运气。

我正在运行 Ubuntu 12.04,并且我已经安装了所有与我有一个模糊想法可能相关的 opengl 相关的开发包。我也在用 C++ 开发,如果没有为它准备好 opengl 头文件,可能会导致问题......但它们是对的吗?

我什至在 /usr/lib/x86_64-linux-gnu/ 中使用 fgrep 显式查找符号,但它不存在,而且 `nm' 表示没有符号。

那么,用 glx 链接的正确方法是什么?

编辑:这是链接问题,当 python 尝试加载已编译(并且链接不正确)的模块时会产生错误。不在编译时。

编辑:这是编译日志

    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.

下面是函数的调用方式:

glXMakeCurrent (dpy, win, ctx);

【问题讨论】:

  • 这个问题缺少重要信息,就像明确指出这是针对 Python 导入模块的。所需信息:源代码大纲、构建配置(Makefile 或类似文件)、编译器标志和全套链接器标志。
  • @datenwolf 我的问题是“在 linux 中链接 glx 的正确方法是什么”......如果答案需要整个世界作为参数......那么我会标记它“Haskell”在那种情况下。
  • 链接 GLX 的正确方法是将 libGL.so 添加到您的链接库集合中 - 您已经这样做了 - 如 Linux OpenGL ABI(可在 OpenGL 网站上找到)中所述。然而,编译后的二进制文件动态链接到另一个程序,必须采取特殊的预防措施。哪些取决于目标程序。
  • @datenwolf 如您所见,目标程序是python的动态模块。并且这些库是在最后一个编译步骤中添加的。我通过添加用于链接中间共享对象的库来修复它,否则链接器只会丢弃它们。

标签: c++ c opengl linker glx


【解决方案1】:

消息“未定义符号”表明它不是链接器,而是编译单元问题:编译器不知道符号glXMakeCurrent,因为它既没有声明也没有定义,但是你使用了它。

可能没有包含 GLX 标头。

添加

#include <GL/glx.h>

事实证明,OP 问题与以下事实有关,即构建由级联共享对象组成,形成一个 Python 模块。一个共享对象实现了实际的 OpenGL 操作,而另一个共享对象负责与 Python 解释器的接口。

现在共享对象 (.so) 本身就是完全限定的 ELF 二进制文件,每个都有自己的导入和导出符号表。可以将共享对象配置为公开它链接到的其他共享对象的所有符号。但是,共享对象将看不到它们链接到的编译单元的任何符号(如果您考虑一下,这是可以预料的,因为共享对象不能也不应该对其将要成为的环境做出任何假设链接到)。

因此,在较大的构建中编译和链接多个共享对象时,将每个共享对象单独链接到运行时所需的任何库非常重要。

【讨论】:

  • 这是一个链接器问题。编译运行完美,甚至链接,因为我正在为 python 生成扩展模块......问题出现在动态链接模块时。
  • 另外,对于未声明的符号,我的 g++ 通常会说“'something' is not declared in this scope”。
  • @dsign:这是您的原始问题缺少的重要信息。您既没有告诉我们您正在尝试创建 Python 模块,也没有告诉我们在尝试加载模块时发生错误。 Python 确实通过 dlopen 加载模块,并且在这种情况下某些事情的工作方式非常不同。您的问题仍然遗漏了重要信息,例如模块代码的基本轮廓、构建配置等。
【解决方案2】:

作为@datenwolf 的方式,链接需要特殊的预防措施。它们是什么对我来说是个谜,但使用 ldd 会有所帮助。所以基本上我所做的是在最终和中间共享对象中使用 ldd 。尽管有命令行参数,但直到我在中间步骤(生成“liblayouter.so”)中还包含“-lGL -lGLU -lX11”之前,我的库才与 libGL 及其依赖项链接。

【讨论】:

  • 其实这并不奇怪,因为显然是 liblayouter.so 需要 libGL.so 的功能。因此,正是这个 .so 必须包含动态链接条目。共享对象 liblayouter_mod.so 反过来会动态链接到 liblayouter.so。现在,如果您将 -lGL 添加到 _mod.so 只有 _mod.so 实际看到 libGL.so 而 liblayouter.so 是干的。还要记住,_mod.so 在它的动态链接器路径中确实需要 liblayouter.so。
  • @datenwolf 感谢您的帮助。我想结束这个问题。你能把你最后的评论作为你的答案,以便我接受吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
相关资源
最近更新 更多