【发布时间】:2020-09-24 15:13:56
【问题描述】:
我在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 库的正常行为。
【问题讨论】:
-
或许比较在两个 Python 二进制文件上检查
ldd的输出会有所帮助。例如,ldd /home/me/.conda/condaenv/proj/bin/python3.7与ldd /home/me/.conda/condaenv/proj/bin/python3.7.bak。随意将这些输出添加到问题中。 -
@merv 感谢您的洞察!我修改了问题。对我来说没有什么不寻常的,但也许你会注意到一些不寻常的东西?
-
是的,我也没有看到太多。我认为您关于编译标志的想法可能是富有成效的。也许值得在 GitHub 上查看 Python 的原料,以确切了解如何为 Conda 构建(例如 Anaconda 或 Conda Forge)完成编译。否则不知道还能去哪里看。
-
也许太明显了,但
sys.path在每种情况下是什么?