我尝试安装Python包dulwich:
pip install dulwich
但我收到了一条神秘的错误消息:
error: Unable to find vcvarsall.bat
如果我尝试手动安装软件包,也会发生同样的情况:
> python setup.py install
running build_ext
building 'dulwich._objects' extension
error: Unable to find vcvarsall.bat
我尝试安装Python包dulwich:
pip install dulwich
但我收到了一条神秘的错误消息:
error: Unable to find vcvarsall.bat
如果我尝试手动安装软件包,也会发生同样的情况:
> python setup.py install
running build_ext
building 'dulwich._objects' extension
error: Unable to find vcvarsall.bat
当前回答
您需要安装一个与用于构建Python的编译器兼容的Microsoft编译器。这意味着您需要Visual C++2008(或更高版本,有一些调整)。
微软现在提供了一个捆绑的编译器和头文件,以便能够在令人难忘的URL上编译Python扩展:
Microsoft Visual C++编译器Python 2.7版http://aka.ms/vcpython27
这是一个相对较小的包装;85MB可下载,无需管理员权限即可安装,无需重新启动。这个名字有点误导人,编译器适用于最初使用Visual C++2008编译的任何Python版本,而不仅仅是Python 2.7。
如果启动Python交互式提示或打印sys.version,请查找MSC版本字符串;如果是MSC v.1500,您可以使用此工具。
从最初的公告到distutils列表:
微软发布了Python 2.7的编译器包,使人们更容易在Windows上构建和分发C扩展模块。Microsoft Visual C++编译器Python 2.7版(又名VC9)可从以下网站获得:http://aka.ms/vcpython27 此包包含为Python 2.7 32位和64位构建C扩展模块所需的所有工具和头文件(请注意,某些扩展模块需要第三方依赖项,如未包含的OpenSSL或libxml2)。也支持使用Visual C++2008构建的Python的其他版本,因此“Python 2.7”只是一个广告——它可以在2.6和3.2中正常工作。
请注意,您需要安装setuptools6.0或更高版本(在下载页面的系统要求中列出)。您正在安装的项目必须使用setuptools.setup(),而不是distutils,否则自动检测将无法工作。
微软表示,他们希望保持URL稳定,以便自动化脚本可以轻松引用它。
其他回答
http://www.stickpeople.com/projects/python/win-psycopg/
从上面的链接安装适当的文件修复了我的问题。
提及:Jason Erickson[jerickso@stickpeople.com]. 他为Windows用户管理这个页面相当好。
如果您希望在未安装Visual Studio的Windows机箱上安装pyodbc,另一种选择是使用二进制发行版手动安装pyodcc。
如果您在正在使用的计算机上没有管理员权限,并且正在尝试设置virtualenv,则这特别有用。
步骤:
从这里下载最新的Windows安装程序(pyodbc-X.X.X.X.win-Y-py2.7.exe)使用7-Zip(或WinRAR等)打开安装程序可执行文件提取pyodbc.pyd和pyodbc-X.X-X-py2.7.egg-info,并将它们放在[python安装目录或virtualenv]\Lib\site包中没有步骤4:)
我尝试了以上所有答案,但发现所有答案都不起作用,这可能是因为我使用的是Windows 8,并且安装了Visual Studio 2012。在这种情况下,这就是你要做的。
vcvarsall.bat文件位于此处:C: \Program Files(x86)\Microsoft Visual Studio 11.0\VC
只需选择文件并复制它。
然后转到以下目录:C: \Program Files(x86)\Microsoft Visual Studio 11.0\Common7\Tools
并粘贴文件。然后,一切都会好起来。
看起来它正在寻找VC编译器,所以您可以尝试使用-c mingw32提及编译器类型,因为您有msys
python setup.py install -c mingw32
调用importsetuptools将对补丁distutils进行模仿,以强制与Visual Studio兼容。手动调用vcvars32.bat将设置虚拟环境并防止编译器抛出其他常见错误。对于VS 2017,文件位于
“C:\Program Files(x86)\Microsoft VisualStudio\2017\社区\VC\Auxiliary\Build\vcvars32.bat“
以下是我用来将.pyx文件快速编译为.pyd的安装脚本:(注意:它使用第三方模块发送2个
# cython_setup.py
import sys, os, time, platform, subprocess
from setuptools import setup, find_packages
from Cython.Build import cythonize
from traceback import format_exc
# USAGE:
#
# from cython_setup import run
# run(pyx_path)
# vcvars = r"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat"
# NOTE: to use visual studio 2017 you must have setuptools version 34+
vcvars = r"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars32.bat"
def _build_ext():
try:
pyx_path = sys.argv.pop(-1)
pyx_path = os.path.abspath(pyx_path)
if not os.path.exists(pyx_path):
raise FileNotFoundError(f"{pyx_path} does not exist")
project_name = sys.argv.pop(-1)
os.chdir(os.path.abspath(os.path.dirname(pyx_path)))
print("cwd: %s" % os.getcwd())
print(os.path.abspath("build"))
setup(
name=project_name,
# cmdclass = {'build_ext': build_ext},
packages=find_packages(),
# ext_modules=cythonize(extensions)
ext_modules=cythonize(pyx_path,
compiler_directives={'language_level': 3, 'infer_types': True, 'binding': False},
annotate=True),
# include_dirs = [numpy.get_include()]
build_dir=os.path.abspath("build")
)
except:
input(format_exc())
def retry(func):
def wrapper(*args, **kw):
tries = 0
while True:
try:
return func(*args, **kw)
except Exception:
tries += 1
if tries > 4:
raise
time.sleep(0.4)
return wrapper
@retry
def cleanup(pyx_path):
from send2trash import send2trash
c_file = os.path.splitext(pyx_path)[0] + ".c"
if os.path.exists(c_file):
os.remove(c_file)
if os.path.exists("build"):
send2trash("build")
def move_pyd_files(pyx_path):
pyx_dir = os.path.dirname(pyx_path)
build_dir = os.path.join(pyx_dir, "build")
if not os.path.exists(build_dir):
raise RuntimeError(f"build_dir {build_dir} did not exist....")
found_pyd = False
for top, dirs, nondirs in os.walk(build_dir):
for name in nondirs:
if name.lower().endswith(".pyd") or name.lower().endswith(".so"):
found_pyd = True
old_path = os.path.join(top, name)
new_path = os.path.join(pyx_dir, name)
if os.path.exists(new_path):
print(f"removing {new_path}")
os.remove(new_path)
print(f"file created at {new_path}")
os.rename(old_path, new_path)
if not found_pyd:
raise RuntimeError("Never found .pyd file to move")
def run(pyx_path):
"""
:param pyx_path:
:type pyx_path:
:return: this function creates the batch file, which in turn calls this module, which calls cythonize, once done
the batch script deletes itself... I'm sure theres a less convoluted way of doing this, but it works
:rtype:
"""
try:
project_name = os.path.splitext(os.path.basename(pyx_path))[0]
run_script(project_name, os.path.abspath(pyx_path))
except:
input(format_exc())
def run_script(project_name, pyx_path):
dirname = os.path.dirname(pyx_path)
# ------------------------------
os.chdir(dirname)
if os.path.exists(vcvars):
# raise RuntimeError(
# f"Could not find vcvars32.bat at {vcvars}\nis Visual Studio Installed?\nIs setuptools version > 34?")
subprocess.check_call(f'call "{vcvars}"', shell=True)
cmd = "python" if platform.system() == "Windows" else "python3"
subprocess.check_call(f'{cmd} "{__file__}" build_ext "{project_name}" "{pyx_path}"', shell=True)
move_pyd_files(pyx_path)
cleanup(pyx_path)
if len(sys.argv) > 2:
_build_ext()