1. 使用pipenv或pip在虚拟环境安装m2crypto报错

使用pipenv或pip在虚拟环境安装m2crypto报错, 报错内容如下:

(env)$ pipenv install m2crypto       # 或: (env)$ pip install m2crypto
Installing initially failed dependencies…
[pipenv.exceptions.InstallError]:   File "/usr/local/lib/python3.7/site-packages/pipenv/core.py", line 1874, in do_install
[pipenv.exceptions.InstallError]:       keep_outdated=keep_outdated
[pipenv.exceptions.InstallError]:   File "/usr/local/lib/python3.7/site-packages/pipenv/core.py", line 1253, in do_init
[pipenv.exceptions.InstallError]:       pypi_mirror=pypi_mirror,
[pipenv.exceptions.InstallError]:   File "/usr/local/lib/python3.7/site-packages/pipenv/core.py", line 859, in do_install_dependencies
[pipenv.exceptions.InstallError]:       retry_list, procs, failed_deps_queue, requirements_dir, **install_kwargs
[pipenv.exceptions.InstallError]:   File "/usr/local/lib/python3.7/site-packages/pipenv/core.py", line 763, in batch_install
[pipenv.exceptions.InstallError]:       _cleanup_procs(procs, not blocking, failed_deps_queue, retry=retry)
[pipenv.exceptions.InstallError]:   File "/usr/local/lib/python3.7/site-packages/pipenv/core.py", line 681, in _cleanup_procs
[pipenv.exceptions.InstallError]:       raise exceptions.InstallError(c.dep.name, extra=err_lines)
[pipenv.exceptions.InstallError]: ['Looking in indexes: http://mirrors.aliyun.com/pypi/simple/', 'Collecting m2crypto==0.35.2', '  Downloading http://mirrors.aliyun.com/pypi/packages/74/18/3beedd4ac48b52d1a4d12f2a8c5cf0ae342ce974859fba838cbbc1580249/M2Crypto-0.35.2.tar.gz (1.1 MB)', 'Building wheels for collected packages: m2crypto', '  Building wheel for m2crypto (setup.py): started', "  Building wheel for m2crypto (setup.py): finished with status 'error'", '  Running setup.py clean for m2crypto', 'Failed to build m2crypto', 'Installing collected packages: m2crypto', '    Running setup.py install for m2crypto: started', "    Running setup.py install for m2crypto: finished with status 'error'"]
[pipenv.exceptions.InstallError]: ['ERROR: Command errored out with exit status 1:', '   command: /Users/xx/.local/share/virtualenvs/iHealth-WeChat-UB3mZpIa/bin/python -u -c \'import sys, setuptools, tokenize; sys.argv[0] = \'"\'"\'/private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/setup.py\'"\'"\'; __file__=\'"\'"\'/private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/setup.py\'"\'"\';f=getattr(tokenize, \'"\'"\'open\'"\'"\', open)(__file__);code=f.read().replace(\'"\'"\'\\r\\n\'"\'"\', \'"\'"\'\\n\'"\'"\');f.close();exec(compile(code, __file__, \'"\'"\'exec\'"\'"\'))\' bdist_wheel -d /private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-wheel-vuqvb4mq', '       cwd: /private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/', '  Complete output (55 lines):', '  running bdist_wheel', '  running build', '  running build_py', '  copying M2Crypto/callback.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/EVP.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/AuthCookie.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/m2.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/ftpslib.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/EC.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/httpslib.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/X509.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/util.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/RSA.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/BIO.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/DH.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/__init__.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/threading.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/Rand.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/SMIME.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/Engine.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/m2xmlrpclib.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/RC4.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/m2urllib2.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/DSA.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/six.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/m2urllib.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/BN.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/m2crypto.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/Err.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  copying M2Crypto/ASN1.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '  creating build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/cb.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/Session.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/timeout.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/__init__.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/TwistedProtocolWrapper.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/Cipher.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/Connection.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/Context.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/SSLServer.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/ssl_dispatcher.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  copying M2Crypto/SSL/Checker.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '  warning: build_py: byte-compiling is disabled, skipping.', '  ', '  running build_ext', "  building 'M2Crypto._m2crypto' extension", '  swigging SWIG/_m2crypto.i to SWIG/_m2crypto_wrap.c', '  swig -python -py3 -I/Users/xx/.local/share/virtualenvs/iHealth-WeChat-UB3mZpIa/include -I/usr/local/python3.6/include/python3.6m -I/usr/include/openssl -I/usr/local/include -I/Library/Developer/CommandLineTools/usr/lib/clang/11.0.0/include -I/Library/Developer/CommandLineTools/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory) -I/usr/local/include -I/Library/Developer/CommandLineTools/usr/lib/clang/11.0.0/include -I/Library/Developer/CommandLineTools/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory) -includeall -modern -builtin -outdir /private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/M2Crypto -o SWIG/_m2crypto_wrap.c SWIG/_m2crypto.i', '  Deprecated command line option: -modern. This option is now always on.', "  SWIG/_m2crypto.i:62: Error: Unable to find 'openssl/opensslv.h'", "  SWIG/_m2crypto.i:68: Error: Unable to find 'openssl/safestack.h'", "  SWIG/_evp.i:12: Error: Unable to find 'openssl/opensslconf.h'", "  SWIG/_rc4.i:5: Error: Unable to find 'openssl/opensslconf.h'", "  SWIG/_ec.i:7: Error: Unable to find 'openssl/opensslconf.h'", "  error: command 'swig' failed with exit status 1", '  ----------------------------------------', '  ERROR: Failed building wheel for m2crypto', '    ERROR: Command errored out with exit status 1:', '     command: /Users/xx/.local/share/virtualenvs/iHealth-WeChat-UB3mZpIa/bin/python -u -c \'import sys, setuptools, tokenize; sys.argv[0] = \'"\'"\'/private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/setup.py\'"\'"\'; __file__=\'"\'"\'/private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/setup.py\'"\'"\';f=getattr(tokenize, \'"\'"\'open\'"\'"\', open)(__file__);code=f.read().replace(\'"\'"\'\\r\\n\'"\'"\', \'"\'"\'\\n\'"\'"\');f.close();exec(compile(code, __file__, \'"\'"\'exec\'"\'"\'))\' install --record /private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-record-mk0tmw37/install-record.txt --single-version-externally-managed --compile --install-headers /Users/xx/.local/share/virtualenvs/iHealth-WeChat-UB3mZpIa/include/site/python3.6/m2crypto', '         cwd: /private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/', '    Complete output (58 lines):', '    running install', '    running build', '    running build_py', '    creating build', '    creating build/lib.macosx-10.15-x86_64-3.6', '    creating build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/callback.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/EVP.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/AuthCookie.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/m2.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/ftpslib.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/EC.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/httpslib.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/X509.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/util.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/RSA.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/BIO.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/DH.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/__init__.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/threading.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/Rand.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/SMIME.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/Engine.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/m2xmlrpclib.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/RC4.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/m2urllib2.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/DSA.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/six.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/m2urllib.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/BN.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/m2crypto.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/Err.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    copying M2Crypto/ASN1.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto', '    creating build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/cb.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/Session.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/timeout.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/__init__.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/TwistedProtocolWrapper.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/Cipher.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/Connection.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/Context.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/SSLServer.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/ssl_dispatcher.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    copying M2Crypto/SSL/Checker.py -> build/lib.macosx-10.15-x86_64-3.6/M2Crypto/SSL', '    warning: build_py: byte-compiling is disabled, skipping.', '    ', '    running build_ext', "    building 'M2Crypto._m2crypto' extension", '    swigging SWIG/_m2crypto.i to SWIG/_m2crypto_wrap.c', '    swig -python -py3 -I/Users/xx/.local/share/virtualenvs/iHealth-WeChat-UB3mZpIa/include -I/usr/local/python3.6/include/python3.6m -I/usr/include/openssl -I/usr/local/include -I/Library/Developer/CommandLineTools/usr/lib/clang/11.0.0/include -I/Library/Developer/CommandLineTools/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory) -I/usr/local/include -I/Library/Developer/CommandLineTools/usr/lib/clang/11.0.0/include -I/Library/Developer/CommandLineTools/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory) -includeall -modern -builtin -outdir /private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/M2Crypto -o SWIG/_m2crypto_wrap.c SWIG/_m2crypto.i', '    Deprecated command line option: -modern. This option is now always on.', "    SWIG/_m2crypto.i:62: Error: Unable to find 'openssl/opensslv.h'", "    SWIG/_m2crypto.i:68: Error: Unable to find 'openssl/safestack.h'", "    SWIG/_evp.i:12: Error: Unable to find 'openssl/opensslconf.h'", "    SWIG/_rc4.i:5: Error: Unable to find 'openssl/opensslconf.h'", "    SWIG/_ec.i:7: Error: Unable to find 'openssl/opensslconf.h'", "    error: command 'swig' failed with exit status 1", '    ----------------------------------------', 'ERROR: Command errored out with exit status 1: /Users/xx/.local/share/virtualenvs/iHealth-WeChat-UB3mZpIa/bin/python -u -c \'import sys, setuptools, tokenize; sys.argv[0] = \'"\'"\'/private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/setup.py\'"\'"\'; __file__=\'"\'"\'/private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-install-06p4c1dw/m2crypto/setup.py\'"\'"\';f=getattr(tokenize, \'"\'"\'open\'"\'"\', open)(__file__);code=f.read().replace(\'"\'"\'\\r\\n\'"\'"\', \'"\'"\'\\n\'"\'"\');f.close();exec(compile(code, __file__, \'"\'"\'exec\'"\'"\'))\' install --record /private/var/folders/v8/hycw3b7x5vz3yv_lsxvg9fym0000gn/T/pip-record-mk0tmw37/install-record.txt --single-version-externally-managed --compile --install-headers /Users/xx/.local/share/virtualenvs/iHealth-WeChat-UB3mZpIa/include/site/python3.6/m2crypto Check the logs for full command output.']
ERROR: ERROR: Package installation failed...

2. 解决方法

先安装opensslswig:

brew install openssl
brew install swig

可以查看openssl安装目录:

$ brew --prefix openssl
/usr/local/opt/openssl@1.1
$ ll /usr/local/opt/openssl@1.1
lrwxr-xr-x  1 xx  admin    28B 10  4 15:01 /usr/local/opt/openssl@1.1 -> ../Cellar/openssl@1.1/1.1.1d

可以知道openssl的实际安装目录是 /usr/local/Cellar/openssl@1.1/1.1.1d/, /usr/local/opt/openssl@1.1 只是 /usr/local/Cellar/openssl@1.1/1.1.1d/ 一个软链接, 得知 /usr/local/opt/ 下存放的都是一些软链接。

/usr/local/include/目录下创建openssl的软链接:

sudo ln -s /usr/local/opt/openssl@1.1/include/openssl /usr/local/include/openssl

/usr/local/lib/目录下创建libssl.dyliblibcrypto.dylib的软链接:

sudo ln -s /usr/local/opt/openssl@1.1/lib/libssl.dylib /usr/local/lib/libssl.dylib
sudo ln -s /usr/local/opt/openssl@1.1/lib/libcrypto.dylib /usr/local/lib/libcrypto.dylib

然后重新安装m2crypto即可安装成功:

(env)$ pipenv install m2crypto       # 或: (env)$ pip install m2crypto