我在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正常行为。
答案 0 :(得分:2)
--without-pymalloc
的{{1}}和--with-pydebug
标志可能导致错误。将miniconda中的./configure
二进制文件替换为python3.7
或./configure --without-pymalloc
构建的二进制文件可防止导入已编译的库,例如./configure --with-pydebug
和math
。没有任何标志(即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。