本文发自 http://www.binss.me/blog/solve-pip-install-pycrypto-failed-on-macos/,转载请注明出处。

今天打算使用一个 python 轮子,依赖于 pycrypto 库,我熟练地通过 pip 进行安装:

pip3 install pycrypto

结果失败报了一坨错误:

clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -fwrapv -Wall -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/usr/local/include -I/usr/local/opt/openssl/include -I/usr/local/opt/sqlite/include -I/Users/binss/syndecrypt-venv/include -I/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/include/python3.7m -c src/MD2.c -o build/temp.macosx-10.14-x86_64-3.7/src/MD2.o
src/MD2.c:30:10: fatal error: 'string.h' file not found
#include <string.h>
         ^~~~~~~~~~
1 error generated.
error: command 'clang' failed with exit status 1

直接原因是找不到 string.h ,本质原因是编译时依赖于写死的路径 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/ 下的内容,而我的机器没安装 Xcode ,因此找不到该文件。

无语,现在写依赖都那么暴力的么。无奈之下,我安装了 Xcode ,结果还是报同样的错误,于是到该目录下一探究竟:

ll /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
total 0
drwxr-xr-x  4 root  wheel  128 Aug 30 14:47 DriverKit19.0.sdk
drwxr-xr-x  6 root  wheel  192 Sep 11 19:47 ..
lrwxr-xr-x  1 root  wheel   10 Sep 21 18:36 MacOSX10.15.sdk -> MacOSX.sdk
drwxr-xr-x  8 root  wheel  256 Sep 21 19:00 MacOSX.sdk
drwxr-xr-x  6 root  wheel  192 Sep 21 19:02 .

显然,没有 MacOSX10.14.sdk ,只有 MacOSX10.15.sdk ,是一个软链,那我们照葫芦画瓢,也建一个软链:

cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
sudo ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk MacOSX10.14.sdk

重新执行 pip3 install pycrypto ,安装成功。

More

到此还是有点不爽,本来硬盘就紧张,现在还要装个没怎么用到的 Xcode ,必须想个办法把它干掉。

按理说,string.h 这种 header 在系统中应该存在才对,不然岂不是随便写个 C 程序都编译不了?这不符合我平常的认知。

突然想起当前在安装 brew 时要求安装一个叫 Xcode Command Line Tools 的东东,它是否包含了我们所需的头文件?

$ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

找到了,其安装在 /Library/Developer/CommandLineTools/ ,一番查找,在该目录下找到了 MacOSX.sdk :/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk ,因此我们应该可以不安装 Xcode ,搞个软链链向这里即可:

sudo mkdir -p /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk MacOSX10.14.sdk

经测试,该方法可行。