我已经连续三天做噩梦了。就像我所做的那样许多我多次下载 Python 的源代码(这次是 2.7.13),并在无法访问互联网的环境中编译它们(因此没有其他方法来获取更新版本的软件)。我使用的是 Oracle Linux 7.3(类似 RHEL 的环境)。默认情况下,它附带了 python 2.7.5,但我需要更新的版本来进行一些测试并获取 pip OOTB。
我做了平常的事:
# ./configure --enable-shared --with-ensurepip
# make
# make install
一切都运行良好,直到我尝试使用 pip 安装一些额外的包,例如 requests。
[root@oel7 python_pkgs]# pip install requests-2.11.1/
Traceback (most recent call last):
File "/usr/local/bin/pip", line 7, in <module>
from pip import main
ImportError: No module named pip
嗯...然后我尝试检查 python 实际安装在什么位置/usr/local/
[root@oel7 ~]# /usr/local/bin/python2.7 --version
Python 2.7.5
因此,我尝试重新编译所有内容,但不安装生成的二进制文件,以查看源目录中实际生成的内容。
[root@oel7 Python-2.7.13]# make distclean
[root@oel7 Python-2.7.13]# ./configure --enable-shared --with-ensurepip
[root@oel7 Python-2.7.13]# ...
[root@oel7 Python-2.7.13]# make
[root@oel7 Python-2.7.13]# ...
[root@oel7 Python-2.7.13]# ./python --version
Python 2.7.5
我现在不知道该怎么办。为什么生成的二进制文件显示其版本是系统默认安装的版本?我还尝试使用另一个前缀但没有成功。
答案1
我...什么...无论如何,这也发生在 Centos 7 上,它或多或少是 RHEL,或多或少是 Oracle linux。值得注意的是,如果我们运行ldd
生成的二进制文件
-bash-4.2$ ldd ./python
linux-vdso.so.1 => (0x00007ffdb238e000)
libpython2.7.so.1.0 => /lib64/libpython2.7.so.1.0 (0x00007fc691bfe000)
...
由于某种原因,2.7.13 的构建已在系统范围的/lib64/libpython2.7*
库(版本 2.7.5)中使用。没有--enabled-shared
正确的版本是2.7.13:
-bash-4.2$ make distclean
...
-bash-4.2$ ./configure --disable-shared --with-ensurepip && make
...
-bash-4.2$ ldd ./python
linux-vdso.so.1 => (0x00007ffffab95000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f59a15a2000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f59a139e000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007f59a119a000)
libm.so.6 => /lib64/libm.so.6 (0x00007f59a0e98000)
libc.so.6 => /lib64/libc.so.6 (0x00007f59a0ad7000)
/lib64/ld-linux-x86-64.so.2 (0x00007f59a17d0000)
-bash-4.2$ ./python --version
Python 2.7.13
-bash-4.2$
这在 python 2.7.13README
文件中完全没有记录,但可以使用LD_*
技巧(或下面的 ELF-mangling 应用程序)来解决 python 构建过程的这一缺陷。还!如果可能的话,避免构建为默认版本,/usr/local
因为这会将您正在构建的任何版本混合到可能存在的任何版本中/usr/local
;如果您确实需要一个程序但希望将实际构建隔离在以下位置,则stow
可以使用GNU或类似的程序:/usr/local/bin/python
/usr/local/python-2.7.13
-bash-4.2$ make distclean
...
-bash-4.2$ ./configure --enable-shared --with-ensurepip --prefix=/usr/local/python-2.7.13
-bash-4.2$ make && sudo make install
...
呃,该LD_RUN_PATH
方法需要两个构建,现在是第二个(第一个构建安装了 2.7.13libpython2.7
库,下一个构建将选择并使用)...
-bash-4.2$ make distclean
...
-bash-4.2$ ./configure --enable-shared --with-ensurepip --prefix=/usr/local/python-2.7.13
...
-bash-4.2$ LD_RUN_PATH=/usr/local/python-2.7.13/lib make
...
-bash-4.2$ ldd ./python
linux-vdso.so.1 => (0x00007ffca7bcd000)
libpython2.7.so.1.0 => /usr/local/python-2.7.13/lib/libpython2.7.so.1.0 (0x00007fc6534fb000)
...
-bash-4.2$ sudo make install
...
-bash-4.2$ /usr/local/python-2.7.13/bin/python --version
Python 2.7.13
-bash-4.2$
使用 ELF 修改工具,其中之一是https://github.com/NixOS/patchef在根据该存储库中的文件进行安装后,README
可以执行单个 python 构建和安装:
-bash-4.2$ sudo rm -rf /usr/local/python-2.7.13
-bash-4.2$ ./configure --enable-shared --with-ensurepip --prefix=/usr/local/python-2.7.13
-bash-4.2$ make
-bash-4.2$ patchelf --set-rpath /usr/local/python-2.7.13/lib python
-bash-4.2$ sudo make install
-bash-4.2$ ldd /usr/local/python-2.7.13/bin/python
linux-vdso.so.1 => (0x00007ffeb57ac000)
libpython2.7.so.1.0 => /usr/local/python-2.7.13/lib/libpython2.7.so.1.0 (0x00007fcea6b75000)
...
-bash-4.2$ /usr/local/python-2.7.13/bin/python --version
Python 2.7.13
-bash-4.2$