记一次在 CentOS7 配置 python3.9 虚拟环境过程

最近做的项目之中需要在服务器跑一跑 TensorFlow 模型,在本地测试时使用的是 Python3.9 版本。但服务器上默认安装的 Python 是 3.6 版本,有很多软件包无法安装。因此有必要安装个 Python3.9。同时,为了避免和已安装版本冲突,我决定采用虚拟环境形式。

此教程也适用于安装多个版本的 Python,解决共存问题。

然鹅,这一看似简单的过程出了不少问题,比如无法引入 ssl、无法连接共享库等等。在此记录分享一下。

0x00 环境准备

安装必要依赖

提前安装好编译 python 可能会用到的一些软件包。

1
yum -y install gcc gcc-c++ zlib-devel bzip2-devel ncurses-devel sqlite-devel readline-devel tk-devel libffi-devel expat-devel gdbm-devel make

升级 GCC

原因

在使用旧版本 GCC 时,如果后续编译 Python 时带有 --enable-optimizations 参数,会报错。

比如:Could not import runpy module

把 GCC 升级到 8.1.0 以上就行了。

确定当前版本
1
gcc --version
下载依赖并升级

这里以 GCC 9.X 为例:

1
yum -y install centos-release-scl
1
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils

如果要其它版本,相应地修改命令中的数字即可。

使配置生效

临时生效,可使用:

1
scl enable devtoolset-9 bash

长期生效,可使用:

1
echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile

(重新登录生效)

安装或升级 OpenSSL

原因

虽然 CentOS7 可通过 yum 将 OpenSSL 升级到 1.0.2 版本(该版本似乎满足 py39 安装要求),但我使用该版本安装后,使用 pip 时,出现了这样的错误:

WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.

我这里把 OpenSSL 升级到 1.1.1 版本后就解决了。

下载源码包并解压
1
2
wget https://www.openssl.org/source/openssl-1.1.1m.tar.gz
tar -zxf openssl-1.1.1m.tar.gz
编译配置
1
2
cd openssl-1.1.1m
./config --prefix=/usr/local/openssl

执行完会显示大概这样的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
......
Using os-specific seed configuration
Creating configdata.pm
Creating Makefile

**********************************************************************
*** ***
*** OpenSSL has been successfully configured ***
*** ***
*** If you encounter a problem while building, please open an ***
*** issue on GitHub <https://github.com/openssl/openssl/issues> ***
*** and include the output from the following command: ***
*** ***
*** perl configdata.pm --dump ***
*** ***
*** (If you are new to OpenSSL, you might want to consult the ***
*** 'Troubleshooting' section in the INSTALL file first) ***
*** ***
**********************************************************************

编译安装
1
make && make install && make clean
环境配置

备份一下原版

1
mv /usr/bin/openssl /usr/bin/openssl.bak
创建软链接
1
2
3
4
5
6
ln -s /usr/local/openssl/include/openssl /usr/include/openssl
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/lib64/libssl.so.1.1
ln -s /usr/local/openssl/lib/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/local/lib64/libssl.so
ln -s /usr/local/openssl/lib/libcrypto.so.1.1 /usr/local/lib64/libcrypto.so

修改系统设置

1
2
3
4
5
6
7
8
# 写入 openssl 库文件的搜索路径
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf.d/openssl-x86_64.conf

# 使修改后的/etc/ld.so.conf生效
ldconfig -v

# 查看所需的动态库
ldd /usr/local/openssl/bin/openssl

检查下版本

1
openssl version -a

应该显示类似这样的内容:

1
2
3
4
5
6
7
8
OpenSSL 1.1.1d  10 Sep 2019
built on: Thu Mar 10 08:32:17 2022 UTC
platform: linux-x86_64
options: bn(64,64) rc4(16x,int) des(int) idea(int) blowfish(ptr)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -O3 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DNDEBUG
OPENSSLDIR: "/usr/local/openssl/ssl"
ENGINESDIR: "/usr/local/openssl/lib/engines-1.1"
Seeding source: os-specific
卸载 openssl-devel

如果系统已经安装 openssl-devel,将其卸载防止冲突。

1
yum remove openssl-devel

0x01 安装Python

下载并解压文件

1
2
3
wget https://www.python.org/ftp/python/3.9.10/Python-3.9.10.tgz
tar -xzf Python-3.9.10.tgz
cd Python-3.9.10

编译安装

编译配置:

这里注意配置好新安装的 openssl 路径。

1
./configure --prefix=/usr/local/python39 --enable-optimizations --with-openssl=/usr/local/openssl --enable-shared

注:在新版本的 python 中(似乎是3.7以上),编译选项 --with-ssl 是无效的。

开始编译:

1
2
3
make -j4 && make altinstall
make clean
make distclean

注:使用 make altinstall 不会自动创建链接,方便保障多个版本共存。-j4 可以适当加快编译速度。

环境配置

配置库文件路径:

1
echo "/usr/local/python39/lib/" >> /etc/ld.so.conf.d/python3.conf

之后刷新缓存:

1
ldconfig -v

注:若不配置,可能出现 libpython3.9.so.1.0: cannot open shared object file: No such file or directory\ 错误。

接下来添加软链接

选择一个主要使用的 Python3 版本,建立软连接:

1
2
ln -s /usr/local/python39/bin/python3.9 /usr/bin/python3
ln -s /usr/local/python39/bin/pip3.9 /usr/bin/pip3

验证结果

1
python3

应显示类似这样的内容:

1
2
3
4
Python 3.9.10 (main, Mar 10 2022, 16:55:34) 
[GCC 11.2.1 20210728 (Red Hat 11.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

0x02 安装 virtualenv

安装虚拟环境好处多多,比如对于不同的工程使用不同的虚拟环境来保持开发环境以及宿主环境的清洁,并且可以自由切换 python 版本。

注:Python3 中自带了虚拟环境,可通过 python -m venv 创建,但我对 virtualenv 比较熟悉,故仍采用。

安装步骤

1
pip install virtualenv

简要使用

介绍一些常用的操作。

创建虚拟环境:

直接运行 virtualenv xxx 即可在当前目录下创建一个名为 xxx 的虚拟环境。

我们这里需要指定一下 python 版本,因此加入 -p 参数。

1
virtualenv py39env -p /usr/local/python39/bin/python3.9

激活环境:

1
2
3
cd py39env/
chmod +x bin/activate
source bin/activate

得到类似输出:

1
(py39env) [root@r3c2 py39env]# 

可以看到最前面有一个小括号,里面是虚拟环境的名字,这样就成功进入了虚拟环境。

还可以验证一下 :

1
which python && which pip

得到:

1
2
/root/ai/py39env/bin/python
/root/ai/py39env/bin/pip

这正是我的虚拟环境的 python 解释器。

接下来就可以愉快使用了~

退出虚拟环境:

1
deactivate

看到最前面的小括号消失即为退出。

如需删除环境,只需 rm -rf py39env 即可。

0x03 完美收工

相关文章:

Centos7使用virtualenv创建python开发环境虚拟环境详解

CentOS 7上安装Python 3.9

End.