Jsonnet 是最近一些深度学习模型的依赖包,本来是很多开发者在Linux上使用的,所以在Windows上的支持不是很好,很多windows用户没办法安装上。那这个教程就是我研究了一下之后给出的Windows上使用pip安装Jsonnet的方法。
首先我是参考这个github issue中的评论:https://github.com/google/jsonnet/issues/476
那我下面就一步一步的说明我的安装过程
第一步,安装MinGW-w64
进去之后点击Files
往下找到MinGW-W64-install.exe,也可以直接点我这里的链接MinGW-W64 Online Installer
然后安装这个MinGW-w64,我是把路径设为 E:\JsonnetEnv\MinGW-64\
然后运行这个exe文件,进去之后记得设置Architecture位x86_64,一路按Next然后设置环境变量,比如我这里就是将E:\JsonnetEnv\MinGW-64\mingw64\bin加入环境变量中的path
这个时候我们在命令行中运行命令查询g++的位置应该可以看到系统的位置跟我们的位置是一致的(或者如果你之前安装过多个MinGW的话就把我们现在安装的这个上移,保证最高优先级调用)
第二步,修改各种配置
打开 ${你安装MinGW的路径}\mingw64\bin,如果你能找到make.exe那么你可以忽略这一步,否则,你需要建立一个符号链接(Symboliclink)。因为我的版本他就是把make命名成了mingw32-make.exe的。具体做法是用管理员权限打开powershell,然后运行下面的代码
New-Item -Type SymbolicLink -Path E:\JsonnetEnv\MinGW-64\mingw64\bin -Name make.exe -Value E:\JsonnetEnv\MinGW-64\mingw64\bin\mingw32-make.exe
这会产生一个make文件的符号链接,然后跟上面一样用where.exe来找一下make.exe的路径:
可以看到我们是弄好了。
第二步,修改pip的默认编译工具
我们这步需要将pip编译的方法从MSVC换成MinGW,那么我们先去找到pip的配置文件:${YOUR_PYTHON_INSTALL_PATH}\Lib\distutils\distutils.cfg
因为我是Anaconda python的所以我本身就有这个文件,如果你没有那么就自己创建一个。
用代码板打开,看到他原来的内容如下:
我们需要改成一下的配置:
[build]
compiler=mingw32
[build_ext]
compiler=mingw32
第四步,下载一下 Visual Studio的build Tools
这里我本身是安装了VS2017 community版本的,所以我就知识下载了Build Tools,我不知道直接安装build Tools行不行。
Build tool 在这里下载:Microsoft Visual C++ Build Tools 2015
下载完就安装就可以了
第五步,给pip打一个补丁
为什么要打这个补丁,就是pip还不能将MSVC和MinGW很好的兼容。详细的解释在这里:https://bugs.python.org/issue25251
大概意思就是苏红,有一个补丁 patch.diff可以让pip在用MinGW编译whl的时候找到所需的dll,但是并不是100%保证成功所以还没放在正式的pip中发布。不过我们现在要装jsonnet的话,用这个刚好可以。
patch.diff,这个文件,右键链接另存为就可以了。
然后进入${你的python根目录}\lib\distutils,复制一下cygwinccompier.py 文件,命名为~cygwinccompiler.py。
然后运行
pip install patch
python -m patch patch.diff
然后将vcruntime140.dll文件复制到 ${你的python根目录}\libs里面,文件可以在这里下载到http://www.xue51.com/soft/1333.html#xzdz
然后在当前目录运行
gendef vcruntime140.dll
然后就会生成vcruntime140.def文件
ok现在你可以用pip来安装jsonnet了
测试一下:
import _jsonnet
jn_str = "{ test: 'foo', other: 'bar' + self.test, /* comment */ }"
json_str = _jsonnet.evaluate_snippet("", jn_str)
print(json_str)
{
"other": "barfoo",
"test": "foo"
}
大功告成了