在用pip安装python包的时候,在用
distutils
发布代码时,可能就会出现这个问题:error: Unable to find vcvarsall.bat
,这个错误表示distutils
无法找到vcvarsall.bat
这个脚本,这个脚本是用来设置编译环境的。
为什么会出现(源码分析)
在distutils
源代码中,有连个用于编译的脚本cygwinccompiler.py
和 msvc9compiler.py
。
- cygwinccompiler.py
实现了CygwinCCompiler
用于支持windows下的Cygwin
- msvc9compiler.py
实现了MSVCCompiler
用于支持Microsoft Visual Studio 2008,这个版本有点低(所以才会出问题。。。)。
搜索一下cygwinccompiler.py
源码可以发现find_vcvarsall
函数是用于获取vcvarsall.bat
所在路径的,我给这个函数写了注释:
def find_vcvarsall(version):
"""Find the vcvarsall.bat file
At first it tries to find the productdir of VS 2008 in the registry. If
that fails it falls back to the VS90COMNTOOLS env var.
"""
#VS的注册表路径
vsbase = VS_BASE % version
try:
#从注册表中获取VS的安装路径
productdir = Reg.get_value(r"%s\Setup\VC" % vsbase,
"productdir")
except KeyError:
log.debug("Unable to find productdir in registry")
productdir = None
if not productdir or not os.path.isdir(productdir):
#获取Path中VS的tools路径的key(VS90COMNTOOLS)
toolskey = "VS%0.f0COMNTOOLS" % version
#VS的tools路径
toolsdir = os.environ.get(toolskey, None)
if toolsdir and os.path.isdir(toolsdir):
#组装出路径 VS_tools_path/../../VC
productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC")
productdir = os.path.abspath(productdir)
if not os.path.isdir(productdir):
log.debug("%s is not a valid directory" % productdir)
return None
else:
log.debug("Env var %s is not set or invalid" % toolskey)
if not productdir:
log.debug("No productdir found")
return None
#组装出路径 VS_tools_path/../../VC/vcvarsall.bat
vcvarsall = os.path.join(productdir, "vcvarsall.bat")
if os.path.isfile(vcvarsall):
return vcvarsall
return None
从代码中可以看出,如果再注册表中没有VS tolls的信息,没有VS90COMNTOOLS
类似的环境变量,就会出现Unable to find vcvarsall.bat
这个错误。
怎么解决
添加注册表项(不推荐)
在注册表添加响应的项,对于64位系统:
在注册表路径添加你的VS的“Setup\VC”目录的绝对路径
Software\Wow6432Node\Microsoft\VisualStudio\~~version~~\Setup\VC
如果是32为系统,则注册表项的key为:
Software\Microsoft\VisualStudio\~~version~~\Setup\VC
添加环境变量(推荐)
在环境变量中添加“ VS90COMNTOOLS
,值为你安装的VS的tools文件夹的绝对路径。下面是具体版本的做法:
- Visual Studio 2010 (VS10): VS90COMNTOOLS=%VS100COMNTOOLS%
- Visual Studio 2012 (VS11): VS90COMNTOOLS=%VS110COMNTOOLS%
- Visual Studio 2013 (VS12): VS90COMNTOOLS=%VS120COMNTOOLS%
- Visual Studio 2015 (VS14): VS90COMNTOOLS=%VS140COMNTOOLS%
下图是我设置的环境变量,如果我安装的是2015,那么我要添加环境变量VS140COMNTOOLS
,值为C:\program files(x86)\Microsoft Visual Studio 14.0\VC\tools\
.
用mingw32编译(不推荐)
如果不想用VS编译,那么就用mingw32编译。首先需要安装mingw32,然后创建文件 C:\Python27\Lib\distutils\distutils.cfg
,内容为:
[build]
compiler=mingw32
但是不推荐,因为在windows下用mingw32编译,难免会水土不服。
VS 2017 怎么办
如果安装了VS 2017,那就稍微麻烦了,因为VS 2017的vcvarsall.bat
跟2015以前的版本目录结构不一样了。在我的64位win7上位置为
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat”
如果是2015,位置则是:
C:\program files(x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
明显不一样了。
这个时候,可以直接修改find_vcvarsall
方法,对python2.7直接修改C:\Python27\Lib\distutils\msvc9compiler.py
文件,例如:
def find_vcvarsall(version):
return r"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat"
大家根据自己的安装路径调整。