【问题标题】:Python executable not finding libpython shared libraryPython 可执行文件找不到 libpython 共享库
【发布时间】:2011-12-14 09:25:23
【问题描述】:

我在 CentOS 5 上安装 Python 2.7。我构建并安装了 Python,如下所示

./configure --enable-shared --prefix=/usr/local
make
make install

当我尝试运行 /usr/local/bin/python 时,我收到此错误消息

/usr/local/bin/python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory

当我在 /usr/local/bin/python 上运行 ldd 时,我得到了

ldd /usr/local/bin/python
    libpython2.7.so.1.0 => not found
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00000030e9a00000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00000030e9200000)
    libutil.so.1 => /lib64/libutil.so.1 (0x00000030fa200000)
    libm.so.6 => /lib64/libm.so.6 (0x00000030e9600000)
    libc.so.6 => /lib64/libc.so.6 (0x00000030e8e00000)
    /lib64/ld-linux-x86-64.so.2 (0x00000030e8a00000)

我如何告诉 Python 在哪里可以找到 libpython?

【问题讨论】:

    标签: python


    【解决方案1】:

    尝试以下方法:

    LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/python
    

    如果/usr/local/lib中没有libpython2.7.so.1.0,则将/usr/local/lib替换为您安装的文件夹/usr/local/lib

    如果这可行并且您希望永久更改,您有两种选择:

    1. export LD_LIBRARY_PATH=/usr/local/lib 添加到您主目录中的.profile 中(这仅适用于您使用的shell 在启动新shell 实例时加载此文件的情况)。此设置只会影响您的用户。

    2. /usr/local/lib 添加到/etc/ld.so.conf 并运行ldconfig。这当然是系统范围的设置。

    【讨论】:

    • 有没有办法导出它以便它与 eclipse 一起工作?我已将它添加到我的 .profile 中,但是 Eclipse 无法启动 gdb。 (注意:将其添加到 ld.so.conf 是可行的)
    • 所以我检查了eclipse运行的环境变量,它确实有正确的LD_LIBRARY_PATH。我相信当它启动 GDB 时,它不使用任何 shell,因此不会获得任何环境变量!在调试配置中设置 libpython 也无济于事,因为这仅适用于 gdb 实际加载时(但我需要 gdb 本身加载的 lib)
    • 当您从命令行运行gdb 并且在终端中正确设置了LD_LIBRARY_PATH 时,您能否成功调试应用程序?如果没有,您可能必须在 .gdbinit 文件中设置 LD_LIBRARY_PATH。有关更多信息,请参阅此答案:stackoverflow.com/a/7041845/156771
    • 我需要 LD_LIBRARY_PATH 来启动 gdb(python 库),而不是用于实际调试我的应用程序。到目前为止,我只能通过在 ldconfig 中设置它来修复它。我可以通过 CLI 调试应用程序,因为它会从我的 ZSHRC 文件中获取 LD_LIBRARY_PATH。
    • 只是给任何尝试这个的人的注释:它只是“/usr/local/lib”,而不是原始“include ld.so.conf.d/*.conf”的起始“include” "。
    【解决方案2】:

    我遇到了同样的问题,我是这样解决的:

    如果你知道 libpython 所在的位置,我想在你的情况下它应该是 /usr/local/lib/libpython2.7.so.1.0,你可以创建一个指向它的符号链接:

    sudo ln -s /usr/local/lib/libpython2.7.so.1.0 /usr/lib/libpython2.7.so.1.0
    

    然后尝试再次运行ldd,看看它是否有效。

    【讨论】:

      【解决方案3】:

      只需安装 python-lib。 (python27-lib)。它将安装 libpython2.7.so1.0。我们不需要手动设置任何东西。

      【讨论】:

      • // 如果你使用的是 CEntOS 6.3?这不起作用,通常人们正在编译 Python 以处理系统 Python 是一个奇怪的版本、损坏、不可靠或其他一些不触及整个系统的情况。
      【解决方案4】:

      我使用命令安装:

      ./configure --prefix=/usr       \
                  --enable-shared     \
                  --with-system-expat \
                  --with-system-ffi   \
                  --enable-unicode=ucs4 &&
      
      make
      

      现在,作为 root 用户:

      make install &&
      chmod -v 755 /usr/lib/libpython2.7.so.1.0
      

      然后我尝试执行python,报错:

      /usr/local/bin/python: 加载共享库时出错: libpython2.7.so.1.0: cannot open shared object file: No such file or directory

      然后,我从 root 用户注销并再次尝试执行 Python,它成功了。

      【讨论】:

        【解决方案5】:

        戴上我的掘墓人帽子...

        我发现解决此问题的最佳方法是在编译时。既然你是唯一的设置前缀,不妨明确地告诉可执行文件在哪里可以找到它的共享库。与 OpenSSL 和其他软件包不同,Python 没有为您提供很好的配置指令来处理备用库路径(不是每个人都是 root 你知道的......)在最简单的情况下,你只需要以下内容:

        ./configure --enable-shared \
                    --prefix=/usr/local \
                    LDFLAGS="-Wl,--rpath=/usr/local/lib"
        

        或者如果您更喜欢非 linux 版本:

        ./configure --enable-shared \
                    --prefix=/usr/local \
                    LDFLAGS="-R/usr/local/lib"
        

        rpath”标志告诉 python 它在该特定路径中有它需要的运行时库。您可以进一步利用这个想法来处理安装到与标准系统位置不同的位置的依赖项。例如,在我的系统上,由于我没有 root 访问权限并且需要进行几乎完全独立的 Python 安装,我的配置行如下所示:

        ./configure --enable-shared \
                    --with-system-ffi \
                    --with-system-expat \
                    --enable-unicode=ucs4 \
                    --prefix=/apps/python-${PYTHON_VERSION} \
                    LDFLAGS="-L/apps/python-${PYTHON_VERSION}/extlib/lib -Wl,--rpath=/apps/python-${PYTHON_VERSION}/lib -Wl,--rpath=/apps/python-${PYTHON_VERSION}/extlib/lib" \
                    CPPFLAGS="-I/apps/python-${PYTHON_VERSION}/extlib/include"
        

        在这种情况下,我将 python 使用的库(如 ffireadline 等)编译到 python 目录树本身的 extlib 目录中。这样我就可以 tar python-${PYTHON_VERSION} 目录并将其放在任何地方,它会“工作”(前提是你没有遇到libclibm 冲突)。当您尝试在同一个机器上运行多个版本的 Python 时,这也很有帮助,因为您无需不断更改您的 LD_LIBRARY_PATH 或担心选择错误版本的 Python 库。

        编辑:忘了提一下,如果你没有将 PYTHONPATH 环境变量设置为你用作前缀的变量,编译会报错并且无法编译某些模块,例如,扩展上例,将PYTHONPATH设置为上例中使用的前缀export PYTHONPATH=/apps/python-${PYTHON_VERSION}...

        【讨论】:

        • // ,这看起来像我要找的。我在哪里可以找到更多关于“tar python-version 目录并将它放到任何地方,它会“工作”(只要你没有遇到 libc 或 libm 冲突)” 的更多信息?您认为值得为此单独提出一个 stackoverflow.com 问题吗?
        • // ,另外,$PYTHON_VERSION应该怎么设置?
        • // ,我在配置后设置了$PYTHON_VERSION。但是,即使设置了$PYTHON_VERSION,编译器也会抱怨Python build finished successfully! The necessary bits to build these optional modules were not found: _bz2 _curses _curses_panel _gdbm _lzma _sqlite3 _tkinter readline
        • // ,这是否需要对make命令和其他安装命令进行任何修改?
        • @NathanBasanese 在缺少 bz2、curses、gdbm、lzma 等的情况下,您需要先编译每一个,并使用前缀 /apps/python-${PYTHON_VERSION}/extlib 以确保它们的库和头文件位于Python make 过程找到的正确位置。至于系统级软件包,您可能会被困在依赖 root 用户预先为您安装这些软件包。或者找到可以编译并登陆extlib的替代方案
        【解决方案6】:

        我在 CentOS 7 上安装了 Software Collections 的 Python 3.5。它本身一切正常,但是当我尝试运行一个简单的 CGI 脚本时,我看到了这个问题中提到的共享库错误:

        tail /var/log/httpd/error_log
        AH01215: /opt/rh/rh-python35/root/usr/bin/python: error while loading shared libraries: libpython3.5m.so.rh-python35-1.0: cannot open shared object file: No such file or directory
        

        我想要一个适用于所有用户的系统范围的永久解决方案,因此不包括将导出语句添加到 .profile 或 .bashrc 文件。有一个基于Red Hat solutions 页面的单行解决方案。感谢您指出这一点的评论:

        echo 'source scl_source enable rh-python35' | sudo tee --append /etc/profile.d/python35.sh
        

        重启后,shell 上一切正常,但有时我的网络服务器仍然报错。还有另一种方法始终适用于 shell 和服务器,并且更通用。我看到了解决方案here,然后意识到它实际上也在这里的一个答案中提到了!无论如何,在 CentOS 7 上,这些是步骤:

         vim /etc/ld.so.conf
        

        我的机器上刚刚有:

        include ld.so.conf.d/*.conf
        

        所以我创建了一个新文件:

        vim /etc/ld.so.conf.d/rh-python35.conf
        

        并补充:

        /opt/rh/rh-python35/root/usr/lib64/
        

        并手动重建缓存:

        sudo ldconfig
        

        就是这样,脚本工作正常!

        这是一个临时解决方案,在重新启动后不起作用:

        sudo ldconfig /opt/rh/rh-python35/root/usr/lib64/ -v
        

        -v(详细)选项只是为了看看发生了什么。我看到它确实做到了: /opt/rh/rh-python35/root/usr/lib64: libpython3.so.rh-python35 -> libpython3.so.rh-python35 libpython3.5m.so.rh-python35-1.0 -> libpython3.5m.so.rh-python35-1.0

        这个特殊错误消失了。顺便说一句,在那之后我不得不chown用户到apache来摆脱权限错误。

        请注意,我使用 find 来定位库的目录。你也可以这样做:

        sudo yum install mlocate
        sudo updatedb
        locate libpython3.5m.so.rh-python35-1.0
        

        在我的虚拟机上返回:

        /opt/rh/rh-python35/root/usr/lib64/libpython3.5m.so.rh-python35-1.0
        

        我需要给ldconfig的路径是什么,如上图。

        【讨论】:

        • 您可以通过转到 /etc/profile.d 并创建一个包含以下内容的文件来为自己省点麻烦:#!/bin/bashsource scl_source enable rh-python35 在其中。 access.redhat.com/solutions/527703
        【解决方案7】:

        这对我有用...

        $ sudo apt-get install python2.7-dev
        

        【讨论】:

        • 您好,这不是正确的解决方案,因为在此之后,您的自定义构建 python 二进制文件将使用您从 apt-get 安装的.so。这可能会在版本相同的情况下出现问题,或者如果您修改了python源代码,则不费吹灰之力。
        【解决方案8】:

        它只需要安装 libpython [3 或 2] 开发文件安装。

        【讨论】:

          【解决方案9】:

          在 Solaris 11 上

          使用 LD_LIBRARY_PATH_64 将符号链接解析为 python 库。

          在我的情况下,python3.6 LD_LIBRARY_PATH 不起作用,但 LD_LIBRARY_PATH_64 起作用。

          希望这会有所帮助。
          问候

          【讨论】:

            【解决方案10】:

            此答案对那些在服务器上具有有限身份验证访问权限的人会有所帮助。

            我在 HostGator 的共享主机中遇到了 python3.5 的类似问题。 Python3.5 必须在登录后的每一次该死的时间内启用。以下是我解决问题的 10 个步骤:

            1. 通过scl脚本python_enable_3.5scl enable rh-python35 bash启用python。

            2. 通过执行python3.5 --version 验证它是否已启用。这应该会给你你的 python 版本。

            3. 执行which python3.5 获取其路径。就我而言,它是/opt/rh/rh-python35/root/usr/bin/python3.5。您可以使用此路径再次获取版本(只是为了验证此路径是否适合您。)

            4. 太棒了,现在请通过scl退出当前shell。

            5. 现在,让我们通过这个完整的python3.5路径/opt/rh/rh-python35/root/usr/bin/python3.5 --version再次获取版本。

              它不会给你版本,而是一个错误。就我而言,它是

            /opt/rh/rh-python35/root/usr/bin/python3.5: error while loading shared libraries: libpython3.5m.so.rh-python35-1.0: cannot open shared object file: No such file or directory
            
            1. 正如Tamas' answer 中提到的,我们必须找到so 文件。 locate 在共享主机中不起作用,您也无法安装。

              使用以下命令查找该文件所在的位置:

            find /opt/rh/rh-python35 -name "libpython3.5m.so.rh-python35-1.0"
            
            1. 上述命令将打印找到后文件的完整路径(第二行)。就我而言,输出是
            find: `/opt/rh/rh-python35/root/root': Permission denied
            /opt/rh/rh-python35/root/usr/lib64/libpython3.5m.so.rh-python35-1.0
            
            1. 这里是 python3.5 在提供版本的共享主机中工作的完整命令,
            LD_LIBRARY_PATH=/opt/rh/rh-python35/root/usr/lib64 /opt/rh/rh-python35/root/usr/bin/python3.5 --version
            
            1. 最后,为简写,在 ~/.bashrc 中附加以下别名
            alias python351='LD_LIBRARY_PATH=/opt/rh/rh-python35/root/usr/lib64 /opt/rh/rh-python35/root/usr/bin/python3.5'
            
            1. 为了验证,通过source ~/.bashrc重新加载.bashrc并执行python351 --version

            好了,你去吧,现在每当你再次登录时,你都有python351欢迎你。

            这不仅限于python3.5,还可以在安装其他scl 软件时有所帮助。

            【讨论】:

              猜你喜欢
              • 2012-08-13
              • 2017-06-18
              • 1970-01-01
              • 2020-06-06
              • 1970-01-01
              • 2017-02-20
              • 2021-07-17
              • 1970-01-01
              • 2023-03-15
              相关资源
              最近更新 更多