python - 编译后的python版本: ModuleNotFoundError at import

标签 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 库的正常行为。

最佳答案

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


旧答案:

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

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--enable-optimizations

关于python - 编译后的python版本: ModuleNotFoundError at import,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64049417/

相关文章:

用于检查进程是否在 Linux 中挂起的 Python 守护进程

python - 超正方体未找到错误 : two docker container python app (docker-compose)

linux - Ubuntu 12.04 - 确认未满足的依赖项

python - 重新排列 python pandas 中的列 : putting last column in the middle

linux - 将调试和 STDOUT 重定向到不同的文件

android - Gradle 构建在全新安装和空项目上永远运行

python - 类型错误 : 'module' object is not callable.

python - 如何将 conda 框架与未上传到 pypi 的包一起使用?

python - Snakemake/miniforge : Nothing provides libgcc-ng >=12 needed by freebayes-1. 3.6-hbfe0e7f_2

python - 在 Mac 中以管理员身份运行已编译的 python (py2app)