我正在尝试在 CentOS 7 上构建支持 SSL 的 Python 3.9.1。
[myuser@server Python-3.9.1]$ which openssl
/usr/local/bin/openssl
[myuser@server Python-3.9.1]$ openssl version
OpenSSL 1.1.1g 21 Apr 2020
运行此命令
sudo ./configure CPPFLAGS="-I/usr/local/openssl/include" LDFLAGS="-L/usr/local/openssl/lib" --with-ssl
后跟“make”适用于 Python 3.7,但是当我在 3.9 上运行上面的代码然后运行 make 时,我得到了这个输出
...
Python build finished successfully!
The necessary bits to build these optional modules were not found:
_lzma _tkinter _uuid
To find the necessary bits, look in setup.py in detect_modules() for the module's name.
The following modules found by detect_modules() in setup.py, have been
built by the Makefile instead, as configured by the Setup files:
_abc atexit pwd
time
Following modules built successfully but were removed because they could not be imported:
_hashlib _ssl
Could not build the ssl module!
Python requires an OpenSSL 1.0.2 or 1.1 compatible libssl with X509_VERIFY_PARAM_set1_host().
LibreSSL 2.6.4 and earlier do not provide the necessary APIs, https://github.com/libressl-portable/portable/issues/381
running build_scripts
creating build/scripts-3.9
copying and adjusting /usr/src/Python-3.9.1/Tools/scripts/pydoc3 -> build/scripts-3.9
copying and adjusting /usr/src/Python-3.9.1/Tools/scripts/idle3 -> build/scripts-3.9
copying and adjusting /usr/src/Python-3.9.1/Tools/scripts/2to3 -> build/scripts-3.9
changing mode of build/scripts-3.9/pydoc3 from 644 to 755
changing mode of build/scripts-3.9/idle3 from 644 to 755
changing mode of build/scripts-3.9/2to3 from 644 to 755
renaming build/scripts-3.9/pydoc3 to build/scripts-3.9/pydoc3.9
renaming build/scripts-3.9/idle3 to build/scripts-3.9/idle3.9
renaming build/scripts-3.9/2to3 to build/scripts-3.9/2to3-3.9
/bin/install -c -m 644 ./Tools/gdb/libpython.py python-gdb.py
gcc -pthread -c -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I. -I./Include -I/usr/local/openssl/include -DPy_BUILD_CORE -o Programs/_testembed.o ./Programs/_testembed.c
gcc -pthread -L/usr/local/openssl/lib -Xlinker -export-dynamic -o Programs/_testembed Programs/_testembed.o libpython3.9.a -lcrypt -lpthread -ldl -lutil -lm -lm
sed -e "s,@EXENAME@,/usr/local/bin/python3.9," < ./Misc/python-config.in >python-config.py
LC_ALL=C sed -e 's,\$(\([A-Za-z0-9_]*\)),\$\{\1\},g' < Misc/python-config.sh >python-config
很明显 Python 3.9 并不是使用 SSL 构建的。我还需要做什么才能使用我安装的 openssl 模块构建 Python 3.9?
上述帖子对指导我的解决方案非常有帮助。我想分享以防其他人可以使用这个:
sudo yum groupinstall "Development Tools" -y
sudo yum install openssl11-devel libffi-devel bzip2-devel xz-devel -y
openssl11-static
因此,出于某种原因,CentOS 提供了
openssl1.1.1
,但它的安装方式与 Python 的 configure
脚本不相符。
# note that we #include <openssl/foo.h>, so the OpenSSL headers have to be in
# an 'openssl' subdirectory
if ! $found; then
OPENSSL_INCLUDES=
for ssldir in $ssldirs; do
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for openssl/ssl.h in $ssldir" >&5
$as_echo_n "checking for openssl/ssl.h in $ssldir... " >&6; }
if test -f "$ssldir/include/openssl/ssl.h"; then
OPENSSL_INCLUDES="-I$ssldir/include"
OPENSSL_LDFLAGS="-L$ssldir/lib"
OPENSSL_LIBS="-lssl -lcrypto"
由于 Python 包含标头,因此需要一个子文件夹:
$ssldir/include/openssl/ssl.h
我刚刚创建了一个具有正确布局的新文件夹:
/opt/openssl111/
├── include
│ └── openssl
│ └── *.h
└── lib
├── libcrypto.so
└── libssl.so
一旦就位,三连胜:
./configure --enable-optimizations --with-lto --with-openssl=/opt/openssl111/
lto
是链接时间优化make -j8
make altinstall
(安装在/usr/local/
中,不会覆盖系统python)问题是因为缺少应该安装的开发库。要安装它们,请按照 CentOS 的Python 开发人员安装文档,运行
sudo yum install yum-utils
sudo yum-builddep python3
运行以下命令来构建Python
./configure
make
make test
sudo make install
如果您想使用自定义 SSL 库构建它,请传递参数
--with-openssl
以及您的库路径。该路径应包含一个包含所需文件的 lib
文件夹。
./configure --with-openssl=<your-openssl-library-path>
编译 Python 时,您需要告诉它要使用哪些 OpenSSL 标头和库。在构建 Python 时运行“
./configure"
”之前尝试此操作
export CFLAGS="$CFLAGS $(pkg-config --cflags openssl11)"
export LDFLAGS="$LDFLAGS $(pkg-config --libs openssl11)"
这是将正确标志传递给编译器和链接器的最可靠方法。还值得检查是否有任何冲突的值被传递到
CFLAGS
/ LDFLAGS
环境变量中,这可能会阻碍您的工作。
显然,这假设您已经安装了
openssl-devel
软件包。 :-)
我相信这是关键:
以下模块已成功构建但已被删除,因为它们 无法导入: _hashlib _ssl
导致这种情况发生的原因是安装在非标准位置的库无法加载。因此,找到该模块(毕竟它已构建)并在其上运行
ldd
。请参阅它的联机帮助页以获取更多详细信息,并记住 Python 模块是共享对象(或 MS Windows 上的 DLL)。它可能会显示缺少对 libssl.so 的依赖项。为了解决这个问题,请配置 Linux 的动态链接器来获取该文件。我想请您参考 man ld.so
获取说明,在此复制该信息是没有用的。
此方法适用于安装 Python 3.9(从源代码),同时合并 OpenSSL 套接字模块。 OpenSSL 也从源代码安装。所有软件包都定向安装在 /usr/local/ 中,以免干扰通过 yum 安装的基本 python 软件包。
首先从源代码安装 OpenSSL:
wget http://www.openssl.org/source/openssl-1.1.1k.tar.gz tar -xzf openssl-1.1.1k.tar.gz cd openssl-1.1.1k sudo ./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl 须藤使 须藤进行安装
从源代码安装 Python3.9,并安装 OpenSSL 作为模块
wgethttps://www.python.org/ftp/python/3.9.6/Python-3.9.6.tgz tar -xzf Python-3.9.6.tgz cd ~/Python3.9.6 sudo ./configure --enable-optimizations --prefix=/usr/local CPPFLAGS="-I/usr/local/openssl/include" LDFLAGS="-L/usr/local/openssl/lib64 --with-openssl= /usr/local/openssl" 须藤使 sudo make altinstall #将Python3.9.6安装到/usr/local
CPPFLAGS --> 编译器标志选项
LDFLAGS --> 链接器标志选项
为Python3.9升级pip:
python3.9 -m pip install --升级pip
Python3.9 -m pip --> 使用最新版本的 pip install(即 pip3)
来自 OpenSSL for Python3 的符号链接共享库文件:
查找/-name libssl.so.3 ln -s /usr/local/lib64/openssl/lib64/libssl.so.3 /usr/lib64/libssl.so.3 ln -s /usr/local/lib64/openssl/lib64/libcrypto.so.3 /usr/lib64/libcrypto.so.3 ldconfig #动态链接器
# try the following:
export CC="gcc"
export CXX="g++"
export CPP="cpp"
export F90="gfortran"
export F77="gfortran"
export FC="gfortran"
dnf install gcc bzip2-devel tk-devel openssl-devel uuid-devel sqlite-devel gdbm-devel readline-devel xz-lzma-compat xz-devel libffi-devel libnsl2-devel
./configure --enable-shared --enable-optimizations
make -j
make install