我尝试安装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

当前回答

我也遇到过同样的问题,所以我将在这里讲述我的故事,希望它能帮助其他人解决同样的问题并节省我刚刚花的几个小时:

我在一个windows7盒子里有mingw(g++(GCC)4.6.1)和python 2.7.3,我正在尝试安装PyCrypto。

在运行setup.py install时,这一切都以以下错误开始:

error: Unable to find vcvarsall.bat

通过将mingw指定为所选编译器,在谷歌搜索错误后轻松解决:

setup.py install build --compiler=mingw32

问题是,然后我得到了一个不同的错误:

configure: error: cannot run C compiled programs.

事实证明,我的防病毒软件阻止了新编译的.exe的执行。我刚刚禁用了防病毒“常驻屏蔽”,并转到下一个错误:

cc1.exe: error: unrecognized command line option '-mno-cygwin' 
error: command 'gcc' failed with exit status 1

这解决了这个问题:“要么安装稍微旧一点的MinGW版本,要么在Python目录中编辑distutils\cygwinccompiler.py以删除-mno-cygwin的所有实例。”(从这里开始)

现在,我终于可以开始工作了。

其他回答

如果您安装了mingw

pip install --global-option build_ext --global-option --compiler=mingw32 packagename

有效,迫使pip使用mingw编译器而不是Microsoft的编译器进行编译。请参见此处https://github.com/pypa/pip/issues/18有关详细信息(上一篇文章)。

看起来它正在寻找VC编译器,所以您可以尝试使用-c mingw32提及编译器类型,因为您有msys

python setup.py install -c mingw32

当我尝试在python 3.5上安装numpy库时,遇到了这个问题。解决方案是安装VS2015。我有VS2008、2012、2013,它们都与python 3.5不兼容。显然,较新版本的python依赖于较新版本VS。

还要确保Visual Studio中安装了C++通用工具。

调用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()

查看您尝试安装的软件包的setup.py文件。如果它是一个较旧的包,那么它可能正在导入distutils.core.setup()而不是setuptools.setup)。

我(在2015年)结合了这些因素:

来自的Microsoft Visual C++编译器Python 2.7http://aka.ms/vcpython27使用distutils.core.setup()的旧包尝试使用python setup.py构建,而不是使用pip。

如果您使用最新版本的pip,它将强制(monkeypatch)包使用setuptools,即使其setup.py调用distutils。但是,如果您不使用pip,而是只使用python setup.py构建,那么构建过程将使用distutils.core.setup(),它不知道编译器的安装位置。


解决方案

步骤1:打开相应的Visual C++2008命令提示符

打开“开始”菜单或“开始”屏幕,搜索“Visual C++2008 32位命令提示符”(如果您的python是32位)或“Visual C++200864位命令提示符(如果您是64位)”。运行它。命令提示符应显示Visual C++2008。。。在标题栏中。

步骤2:设置环境变量

在刚刚打开的命令提示符中设置这些环境变量。

SET DISTUTILS_USE_SDK=1
SET MSSdk=1

参考http://bugs.python.org/issue23246

步骤3:构建和安装

cd到要构建的包,然后运行pythonsesetup.pybuild,然后运行python setup.pyinstall。如果要安装到virtualenv,请在构建之前激活它。