文章目录
- 前情提要
- 安装 openssl-1.1.1
- 重新编译安装 python3.8
- -rpath 编译选项介绍
- python3.8 跟 python3.10 的区别
前情提要
在我成功给 python3.10 安装 ssl 模块后自以为是的写下了 “虽然我编译的是 python3.10,但是对于 python3.6、python3.8 应该同样适用。” 这句话。今天晚上我尝试给压测服务器安装一个带 ssl 模块的 python3.8 的时候,照着自己写的博客一步步来,然后失败了-_-||。
安装 openssl-1.1.1
- wget https://www.openssl.org/source/openssl-1.1.1n.tar.gz --no-check-certificate 下载openssl1.1.1
- tar zxf openssl-1.1.1n.tar.gz 解压
- cd openssl-1.1.1n
- ./Configure --prefix=/usr/local/openssl 设置安装目录 可以自定义 但是要记住,后面会用到
- make -j && make install 编译并安装
- cd /usr/local/openssl/lib
- mv libcrypto.so libcrypto.so.1 修改动态库名字,随便改一下就行,当一个备份
- mv libssl.so libssl.so.1 同上
- ln -s libcrypto.so libcrypto.a 创建一个假动态库,实际上是静态库的软链接
- ln -s libssl.so libssl.a 同上
重新编译安装 python3.8
我的版本是 python3.8.0 ,其他版本不保证有效-_-||
- 切换到 python3.8 解压包目录
- 已经编译过的可以先 make clean 清理一下
- yum install libffi-devel -y 安装 libffi-devel ,这个是为了 _ctypes 模块
- ./configure --prefix=/usr/local/python3 --with-openssl=/usr/local/openssl --with-ssl-default-suites=openssl --with-system-ffi
- make -j && make install
到这应该安装成功了,如果还有问题的话留言讨论吧-_-||
-rpath 编译选项介绍
-rpath 是 gcc 的一个编译选项,用于指定程序运行时动态链接库的搜索路径。当程序运行时需要动态链接库时,系统会在指定的路径中搜索动态链接库。
例如,假设有一个程序 a.out,它需要动态链接库 libfoo.so,而 libfoo.so 位于 /usr/local/lib 目录下,那么可以使用以下命令编译程序:
gcc -o a.out a.c -L/usr/local/lib -lfoo -Wl,-rpath=/usr/local/lib
其中,-L 选项指定编译器在编译时搜索库文件的路径,-l 选项指定需要链接的库文件名。-Wl,-rpath=/usr/local/lib 选项指定程序运行时搜索动态链接库的路径。
这样,当程序 a.out 运行时,系统会在 /usr/local/lib 目录下搜索 libfoo.so 动态链接库。
python3.8 跟 python3.10 的区别
查看 python3.8 配置脚本关于 openssl 的帮助信息
查看 python3.10.3 配置脚本关于 openssl 的帮助信息
python3.10.3 中多出来的这个选项是说是否在 gcc 编译的时候传递 -rpath 选项给编译器,所以可以按我这篇文章中的做法处理。
python3.8 的配置脚本没有这个选项,但是他编译过程中又查找的是名为 libssl.so 的动态库。这时候我们不能传递 -rpath=/usr/local/openssl/lib, 只能采取其他办法,想来这也是 3.10 新增选项的原因。
那要怎么解决这个问题呢,我想到有四种解决方案:
-
就是我上面所做的那样,将动态库文件名实际指向静态库,这样即使没有 -rpath 选项,也没关系了,因为跟 python 编译链接的是静态库,而静态库的路径已经由 --with-openssl=/usr/local/openssl 选项指定了。
-
修改 python 的编译脚本,强行指定 -rpath,这种做法和官方 3.10 做的效果一样。
-
在系统的动态库默认搜索路径下创建一个指向 /usr/local/openssl/lib/ 下两个需要的动态库的软链接。
Linux系统默认的C动态库搜索目录包括以下几个:/lib /usr/lib /usr/local/lib
这些目录是在系统启动时就被设置好的,当程序需要链接动态库时,系统会自动在这些目录中搜索相应的库文件。如果你想添加其他目录到动态库搜索路径中,可以使用 LD_LIBRARY_PATH 环境变量来实现。
-
如上一个方法末尾所说那样,将 /usr/local/openssl/lib 添加到 LD_LIBRARY_PATH 环境变量中,这样做感觉是最合理的解决方案了。读者可以自己尝试这几种方案,因为我用 python 并不深入,只是作为工作中的工具使用,能用就行,有问题再说。