【问题标题】:Cython not finding shared libraryCython 找不到共享库
【发布时间】:2014-06-13 06:41:05
【问题描述】:

我的问题开始时与此相同:Python executable not finding libpython shared library

我用export LD_LIBRARY_PATH=$HOME/local/lib/python/2.7.6/lib 更新了.bashrc,一切都很好。 Python 工作,我安装了 pip。但是现在,我在使用 pip 安装 cython 时遇到了类似的情况。我在执行pip install cython 时收到此错误消息:

gcc -pthread -shared build/temp.linux-x86_64-2.7/tmp/pip_build/cython/Cython/Plex/Scanners.o -L. -lpython2.7 -o build/lib.linux-x86_64-2.7/Cython/Plex/Scanners.so

/usr/bin/ld: cannot find -lpython2.7

collect2: ld returned 1 exit status

error: command 'gcc' failed with exit status 1

我无法将$HOME/local/lib/python/2.7.6/lib 添加到/etc/ld.so.conf 并运行ldconfig,因为我没有root。我的印象是设置 LD_LIBRARY_PATH 是解决这个问题的方法,但这似乎不适用于编译。有没有办法让编译器在不运行 root 命令的情况下查看这个本地库?

【问题讨论】:

    标签: linker cython


    【解决方案1】:

    更新:

    LD_LIBRARY_PATH 仅由动态加载器在运行时使用,而不是在构建时使用,所以这不是问题。问题是您忘记将-L/path/to/pylib 放在-l 之前。我从来不需要使用LIBRARY_PATH,因为构建需要特定于给定构建的路径扩展,所以你永远不会设置LIBRARY_PATH,你只需使用-L。如果您要定期进行使用特定库的构建,您只会设置,即使那样我发现使用 -L 更好,因为迟早这会导致链接器找到错误的库,到那时您会忘记那是因为LIBRARY_PATH 是永久设置的。

    有很多方法可以在构建中设置 -L 值:如果从命令行运行编译器,则不需要该 env var,只需在命令中指定所需数量的 -L;如果您使用makefile,您可以编辑您正在使用的任何make 变量,例如CFLAGS 或其他,不同的平台有不同的约定。因此,虽然直接设置 -L 将始终有效,但设置 CFLAGS 仅在生成文件使用的变量时才有效。

    现在这是一个 python 安装,所以在哪里设置它可能并不明显,但我确信除了设置 LIBRARY_PATH 之外还有另一种方法。原则上,您安装的任何 python 包,如果它涉及 C++ 模块的编译,都可能需要编辑 setup.py 以设置库路径。例如

    Extension(...,
              library_dirs=['/usr/X11R6/lib'],
              ...)
    

    既然你提到了 nympy,另一个设置它的地方可能是site.cfg(参见Supplying NumPy site.cfg arguments to pip)。

    旧(错误)答案:

    在 bash 控制台中设置您的 LD_LIBRARY_PATH。如果这不起作用,那是因为您的路径错误:通过回显环境变量进行检查。

    一旦你让它工作,编辑你的 .bashrc 或 .profile 然后退出你的 shell 并重新启动它。回显 env var 以验证是否包含您添加的部分。

    另外,请确保您附加到路径而不是覆盖它:

    LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/...
    export LD_LIBRARY_PATH
    

    因为 python 库可能依赖于其他文件夹中的 .so,如果链接器找不到它们,它可能看起来好像是未找到的 python 库。您在问题中链接到的页面上没有说明这一点。

    【讨论】:

    • 我试过你提到的东西,但没有运气。我可以通过运行CFLAGS="...pypath.../lib" python setup.py install 来构建 cython。感觉不对,但至少它是建立起来的。但是,当我尝试使用类似的技巧构建 numpy 时,我遇到了同样的问题,但使用的是 gfortran。同时指定 CFLAG 和 FFLAG 不起作用。有点不对劲。
    • 在您的更新中:是的,这就是我之前的评论允许 cython 编译的原因。我实际上是想把 CFLAGS="-L...pypath.../lib"。这更像是一种解决方法,因为它不适用于我提到的 numpy 安装。将LIBRARY_PATH 设置为使编译器了解...pythonpath.../lib 目录中的libpython2.7.so 的正确方法。不过,我很感谢您抽出时间来看看这个。
    • @ChesterVonWinchester 好吧,我想赞成你的答案,因为它包含一个关键线索,但我不能,因为它不是答案。答案是使用 -L (显然你是在暗示,但我没有明白),如何使用它取决于你的具体情况,正如我在更新的答案中所解释的那样。
    • 就我而言,设置LIBRARY_PATH 是一个更好的解决方案。设置-L 选项并不像我运行python setup.py 脚本那样简单地在makefile 中添加这个标志。即使我可以将它附加到特定包的 setup.py 文件中的所有适当位置,这可能不适用于所有包,迫使我修改 setup.py 并为每个新包编译标志(参见 cython与第一条评论中的 numpy 相比)。我看到将LIBRARY_PATH 设置为ldconfig 的本地版本,这正是我需要的,因为我没有root。
    • 除此之外,我将您的问题标记为答案,因为这个问题更多地是关于编译时链接的问题,而不是关于 cython 或 python 的问题,您的回答在这方面为一般情况提供了更好的建议。
    【解决方案2】:

    好吧,经过一番挖掘,我发现了这个:LD_LIBRARY_PATH vs LIBRARY_PATH

    LIBRARY_PATH 设置为与LD_LIBRARY_PATH 相同的路径使编译器能够识别python 库。 cython/numpy/scipy 全部构建安装没问题。

    【讨论】:

    • 啊,当然,现在我看到了这个问题,我已经更新了我的答案,希望它可以工作(我从来没有设置那个环境变量,所以请尝试更新)。
    猜你喜欢
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    相关资源
    最近更新 更多