【问题标题】:New at Python: GLPK not building properly / Python ImportErrorPython 的新功能:GLPK 未正确构建 / Python ImportError
【发布时间】:2010-04-28 09:52:54
【问题描述】:

这是一个初学者问题,是this one 的后续问题,我在其中被指向 GLPK。

我正在尝试启动并运行PyGLPK,这是一个用于GNU Linear Programming Kit 的 Python 绑定,但无论我做什么,我似乎都无法构建和安装 GLPK,以便 Python 正确找到它。这是在 GLPK 库上运行 ./configure、make 和 sudo make install 并遵循 PyGLPK 的说明之后发生的。

具体来说,这是我得到的错误:

>>> import glpk  
Traceback (most recent call last):  
File "<stdin>", line 1, in <module>  
ImportError:    dlopen(/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-    packages/glpk.so, 2): Symbol not found: __glp_lpx_print_ips
   Referenced from:     /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/glpk.so
   Expected in: dynamic lookup

我假设某些东西没有链接到其他地方,并且它可能与路径和环境变量有关。然而,这就是我在 shell 中的能力失败的地方,我不知道下一步该做什么。

编辑

  1. 我可以从命令行运行 GLPK Solver (glpsol),所以我知道它可以工作,至少在理论上是这样。

  2. 有一次我尝试使用 MacPorts 安装一个 GLPK 版本。我已经卸载了这个版本,尽管使用的是 MacPorts。

  3. 这是使用otool -L 的结果,这显然是ldd 的OS X 答案:

    /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/glpk.so:   
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.11)
    

同样,这可能有一个简单的答案,但我对使用我知道的术语的谷歌没有任何运气。

【问题讨论】:

  • glpsol 命令确实起作用的事实仅仅意味着它可能正确链接到 GLPK C 库。这可能意味着该工具是静态链接的,或者它可能是使用显式 RPATH(运行时库搜索路径)编译的,或者它可能是使用不同参数编译的。您仍然需要弄清楚它与 glpk.so 扩展模块的构建方式有何不同。

标签: python unix installation module importerror


【解决方案1】:

这个问题并不是 Python 所特有的。 glpk 模块是一个扩展模块,一个 Python 加载的 C 共享库。该 C 共享库依赖于它所包装的 GLPK C 库;加载扩展模块应该加载 GLPK C 库,以便扩展模块可以引用 GLPK C 库中的符号,例如__glp_lpx_print_ips。显然,有些事情失败了。它可能是以下几种情况之一:

  1. glpk.so 扩展模块可能根本没有链接到 GLPK C 库。这意味着它是在没有链接到 GLPK 库所需的 -l 参数的情况下构建的,这意味着问题出在 glpk 扩展模块的构建过程中。您可以使用ldd 工具判断glpk.so 是否依赖于C 库。例如:

    % ldd /usr/lib/python2.6/lib-dynload/gdbm.so 
    linux-gate.so.1 =>  (0xb77bb000)
    libgdbm.so.3 => /usr/lib/libgdbm.so.3 (0xb7799000)
    libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7780000)
    libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7639000)
    /lib/ld-linux.so.2 (0xb77bc000)
    

    这表明我的 gdbm 扩展模块与 libgdbm 共享库(以及其他共享库)链接。

  2. glpk.so 扩展模块可能正确链接到 GLPK C 库,但动态链接器可能无法找到 C 库。通常这会产生不同的警告(关于无法找到 C 库),但这可能不会在 MacOS 上发生。您可以再次使用ldd 工具看到这一点:它会列出依赖项,但不会列出加载的实际文件(它会显示“未找到”。)

    这通常是由于未安装 C 库,或者将其安装在动态链接器不知道要查找的位置造成的。不幸的是,我不知道 MacOS X 如何进行库查找,以及您应该如何修改它扫描的路径。 (在大多数 UNIX 系统上,您可以编辑 /etc/ld.so.conf/etc/ld.so.conf.d/ 中的文件,或运行 ldconfig -m。)

  3. glpk.so扩展模块可能链接正确,动态链接器也可能正确找到该模块,但GLPK扩展模块可能根本没有定义这个符号。这可能是 GLPK 中的一个错误,也可能是因为动态链接器正在查找 不同 GLPK C 库(不同的版本,或者构建方式不同的库),或者可能是因为 GLPK C 库的编译方式与 glpk.so 扩展模块不同。不过,这有点难以诊断,因为这意味着要深入研究实际的 C 库符号和编译期间使用的头文件。

我猜,考虑到所有因素,问题是 #2。这是最常见的问题,尤其是在/usr/local 中安装时,这是./configure 没有--prefix 参数通常会发生的情况。

【讨论】:

  • 更多关于网络的讨论让我认为动态链接过程出了点问题——可能是在构建过程中,但目前我无法测试和修复它。事实上,我很想获得一个资源来解释构建过程中发生的事情以及我如何控制它。
【解决方案2】:

问题解决了!

Thomas Wouter 的第一个建议最接近标记:glpk.so 模块根本没有链接到 C 库。原因是make 使用gcc4.2 构建了原始的GLPK 库并指定了64 位架构,而Python 的distutils 模块坚持使用gcc-4.0 构建32 位架构的PyGLPK 源代码。

由于我不知道如何将编译器标志添加到distutils,我只是重建了强制distutils 编译器标志的 GLPK 库。这就是最终奏效的方法。

这似乎是 OS X 10.6 的问题。 ./configure 脚本查询系统架构,我认为默认情况下是 x86_64,尽管 Python 2.6 最适合 32 位二进制文​​件。

【讨论】:

    猜你喜欢
    • 2017-07-26
    • 1970-01-01
    • 2022-10-04
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 2021-10-27
    • 2021-04-28
    • 2015-09-17
    相关资源
    最近更新 更多