mac 10.14 源代码编译Python3.6.5的总结

    说明

    为什么我一个做PHP课程的要发Python的内容?因为我也做Python!

    目的

    mac 上安装了多个Python版本,其中 3.6.5 的版本无法使用ssl,表现形式为:pip install 和 import ssl 模块时报错。

    背景

    操作系统:mac 10.14

    openssl

    通过 brew 安装在 /usr/local/Cellar/openssl/1.0.2p 并且在 /usr/local/opt/openssl 做了它的软连接。

    通过 brew list openssl 可以查看到相关文件。

    其他解决方法

    pyenv

    据说这是一个多版本python的管理工具,但是鉴于小师弟之前出现的问题,所以我不想承担这个风险,放弃。

    给现有的python3.6.5 补充 ssl 功能

    遍寻无果,也许是不能补充吧,所有的方案都是重新编译。

    通过 brew 安装指定版本

    我的电脑已经安装了 brew,并且通过brew安装了 python3.7的版本。

    据说可以,brew install homebrew/version/form 类似这样的命令来实现安装指定版本,最终我并没有找到可用的方法。

    源代码编译 Python 3.6.5

    最终选择该方法“解决问题”。

    • 优点
      • 源代码编译安装,更容易掌控细节。
    • 缺点
      • 麻烦

    下载源文件

    在 Python.org 上下载 3.6.5 的源文件(.tgz),解压缩到目标文件夹。

    执行编译

    ./configure --prefix=/usr/local/Cellar/python/3.6.5 \ 
    --with-ssl=/usr/local/opt/openssl
    make
    make install
    

    注:Cellar 目录似乎是 brew 安装的默认路径(在 /usr/local/opt/ 下做了很多软连接到这里)

    报错1:zlib 不可用

    zlib 是一个扩展,装一下吧 brew install zlib,安装成功。

    给 configure 补充参数 --with-zlib=/usr/local/opt/zlib,结果还是报错,中间尝试了各种方法。

    比较多人说需要xcode-select --install,我相信有很多人用这个语法解决了问题,但我不行(因为我已经安装过这个了)

    最后一个老外给出了我要的答案,在 mac 10.14 版本的操作系统中,需要先执行一个命令:

    sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
    

    命令需要执行一会儿,大概就是安装一个headers 的包吧,并未深究。安装后解决了 zlib 的问题。

    注意:并不需要 --with-zlib 这个参数,系统会自动匹配的(这个选项这是我臆想出来的)

    编译成功

    没有报任何错误,但是我执行刚刚创建的 python3.6.5/bin/python 后,import ssl 依然提示找不到模块,说明编译通过但是 ssl 的问题并未解决。

    解决openssl 的问题

    我使用的方法,需要修改源文件,进入解压缩后的 python3.6.5文件夹,找到如下文件一一进行修改。

    修改 setup.py

    将文件中所有出现 /usr/local/ssl 的路径,改为 /usr/local/Cellar/openssl/1.0.2p。(应该有两处)

    注意:这个路径是我的 openssl 安装路径,根据电脑不同可能有所变化。

    修改 modules/setup.dist

    搜索 #SSL=,可以找到如下这4行代码(下面是我修改完毕的样子)

    • 取消注释
      • 将他们前面的#号删除掉
    • 修改路径
      • SSL=你的openssl 安装路径
    SSL=/usr/local/Cellar/openssl/1.0.2p
    _ssl _ssl.c \
        -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
        -L$(SSL)/lib -lssl -lcrypto
    

    重新编译

    最终使用的编译命令

    ./configure --prefix=/usr/local/Cellar/python/3.6.5
    make
    make install
    

    顺利的话,编译可以通过。如果出现 找不到openssl/rsa.h 这样的错误,说明你之前的路径改的不彻底。

    测试效果

    执行 安装路径/bin/python3.6,进入交互式界面输入import ssl,回车后没有报错算成功,如果提示模块不存在,那么问题依然没有解决。

    我通过了!

    做软连接

    去 /usr/local/bin/ 下面,删除(或备份)python3.6python3.6mpython3.6-configpython3.6m-config

    然后用软连接,将这4个文件名,分别指向到 /usr/local/Cellar/python/3.6.5/bin/ 下的对应文件名。

    软连接语法:ln -s 源文件 目标文件

    pipenv

    去项目exchange_rate 中 pipenv uninstall 删除当前环境,重建pipenv --python 3.6.5版本,通过。

    进入虚拟环境后,通过 pip install sound-machine 可以下载和安装扩展,说明ssl的问题算彻底解决了。

    总结

    这次主要出了两个问题:

    • zlib
      • 原因是操作系统的版本问题
    • openssl
      • 原因是 openssl 路径问题

    我下载的 python 源码包,应该是给linux用的,因为openssl默认路径不对,但是我很奇怪:难道不应该有一个参数来指定 openssl 的路径吗?是我没找到,还是真的没有?

    或者

    我应该下载他们提供的 mac 版本,这里:python download for macOS,但是我担心它会主动修改环境变量、软连接等,影响我的其他版本,所以没有尝试。

    遗憾

    有问题的 3.6.5 版本依然在系统里,我没有删除它(不确定如何彻底删除)

    不确定日后是否还有其他遗留问题。