编译的python版本:导入时出现ModuleNotFoundError

时间:2020-09-24 15:13:56

标签: python linux conda

我在conda环境中有一个项目,该项目使用python 3.7.7(在Linux上)运行。当我重新编译相同版本的python(3.7.7)并将可执行文件放置/替换在同一位置时,我希望程序以相同的方式运行,但是导入失败。

使用python的原始版本:

(condaenv) mypc:~/Proj$ /home/me/.conda/envs/condaenv/bin/python3.7.bak
Python 3.7.7 (default, Mar 26 2020, 15:48:22) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import gym
>>> quit()

具有编译版本:

(condaenv) mypc:~/Proj$ /home/me/.conda/condaenv/proj/bin/python3.7
Python 3.7.7 (default, Sep 24 2020, 16:28:06) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import gym
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'gym'
>>> quit()

假定环境变量与我在同一终端上从同一位置运行的环境变量相同,而在两次调用之间未对其进行更改。由于首次导入可以正常进行,因此软件包安装正确。

系统导入,例如sys在这两个版本中都可以正常工作,但是对于编译后的版本,我必须先导出LD_LIBRARY_PATH,而对于“普通”版本则不是这样。但是在两个调用之间保持LD_LIBRARY_PATH不变不会改变任何内容。

第二个调用找不到匹配的程序包怎么办?我想念什么?

-编辑1 -

编译后版本的共享库依赖关系如下:

$ ldd python3.7
        linux-vdso.so.1 (0x00007ffed457a000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f63e53a6000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f63e53a0000)
        libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f63e539b000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f63e524c000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f63e505a000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f63e577f000)

原始的python如下:

$ ldd python3.7.bak 
        linux-vdso.so.1 (0x00007ffc0d1c8000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f89ab6bc000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f89ab4ca000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f89ab4c4000)
        libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f89ab4bf000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f89ab4b4000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f89ab365000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f89aba80000)

版本有所不同,因为它们没有使用相同版本的编译器进行编译(我想)。但是,令我感到惊讶的是,新版本不需要librt.so,而原始版本却需要。不过,可能是由于编译标志阻止了优化。我在配置步骤中添加了--without-pymalloc --with-pydebug --with-valgrind。但是我认为它不会干扰库的python正常行为。

2 个答案:

答案 0 :(得分:2)

--without-pymalloc的{​​{1}}和--with-pydebug标志可能导致错误。将miniconda中的./configure二进制文件替换为python3.7./configure --without-pymalloc构建的二进制文件可防止导入已编译的库,例如./configure --with-pydebugmath。没有任何标志(即numpy)的编译不会导致这些错误。导入编译的库时,使用./configure && make进行编译也不会引发错误。


旧答案:

您可以尝试使用configure flags used by conda-forge吗?使用这些标志,我能够在conda环境中替换./configure --with-valgrind二进制文件,并且导入继续起作用。如果我使用了OP的标志(即python3.7),则无法导入已编译的库(例如math,numpy)。

--without-pymalloc --with-pydebug --with-valgrind

解决方案涉及这些标志之一-可能是curl -L https://www.python.org/ftp/python/3.7.7/Python-3.7.7.tar.xz | tar xJ cd Python-3.7.7 ./configure \ --prefix=/tmp/python3.7 \ --enable-ipv6 \ --with-ensurepip=no \ --with-computed-gotos \ --with-system-ffi \ --enable-loadable-sqlite-extensions \ --with-lto \ --enable-optimizations \ --with-valgrind make -j --with-lto

答案 1 :(得分:0)

您在哪里编译了新的Python?可能是缺少的lib librt.so.1是错误消息的元凶。有没有机会安装librt软件包(取决于您的Linux风格)并重新编译Python。