运行python setup.py install时强制编译

时间:2015-10-25 15:41:06

标签: python cython setuptools anaconda

有没有办法在运行python setup.py install时显式强制编译器构建Cython扩展?其中setup.py的格式为:

import os.path
import numpy as np
from setuptools import setup, find_packages, Extension
from Cython.Distutils import build_ext

setup(name='test',
  packages=find_packages(),
  cmdclass={'build_ext': build_ext},
  ext_modules = [ Extension("test.func", ["test/func.pyx"]) ],
  include_dirs=[np.get_include()]
 )

我正在尝试使用Anaconda 3.16,Python 3.4,setuptools 18,Numpy 1.9和Cython 0.24在Windows 8.1 x64上安装软件包。部署脚本改编自Cython wikithis Stack Overflow答案。

Makefile.bat

:: create and activate a virtual environement with conda
conda create --yes -n test_env cython setuptools=18 pywin32 libpython numpy=1.9 python=3
call activate test_env

:: activate the MS SDK compiler as explained in the Cython wiki
cd C:\Program Files\Microsoft SDKs\Windows\v7.1\
set MSSdk=1
set DISTUTILS_USE_SDK=1
@call .\Bin\SetEnv /x64 /release 

cd C:\test
python setup.py install

问题是在这种情况下setup.py install仍然使用conda附带的mingw编译器而不是MS Windows SDK 7.1。

  • 因此DISTUTILS_USE_SDK=1MSSdk=1似乎对buid没有影响。我不确定是否在conda virtualenv中激活MS SDK可能是一个问题。

  • 正确运行python setup.py build_ext --compiler=msvc使用MS编译器构建扩展,但随后运行setup.py install,再次使用mingw重新编译它。同样适用于python setup.py build --compiler=msvc

  • 还尝试按照上面链接的答案中的讨论运行%COMSPEC% /E:ON /V:ON /K "%PROGRAMFILES%\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd",但对我来说,这会产生一个新的终端提示,颜色为黄色,并停止安装过程。

有没有办法强制编译器构建这个包,例如,通过编辑setup.py

4 个答案:

答案 0 :(得分:15)

您可以在名为setup.cfg的单独文件(与setup.py平行放置)中为distutils提供(默认)命令行参数。有关详细信息,请参阅docs。要设置编译器,请使用以下内容:

[build]
compiler=msvc

现在调用python setup.py build相当于调用python setup.py build --compiler=msvc。 (您仍然可以通过调用python setup.py build --compiler=someothercompiler

来指示distutils使用其他编译器

现在你已经成功指导了distutils使用 a msvc编译器。不幸的是,没有选择告诉它使用哪个 msvc编译器。基本上有两种选择:

一个:什么也不做,distutils会尝试找到vcvarsall.bat并使用它来设置环境。 vcvarsall.bat(以及为其设置环境的编译器)是Visual Studio的一部分,因此您必须安装它才能使其正常工作。

二:安装Windows SDK并告诉distutils使用它。请注意,名称DISUTILS_USE_SDK相当具有误导性(至少在我看来)。它实际上并不告诉distutils使用SDK(以及它setenv.bat)来设置环境,而是意味着distutils应该假设已经设置了环境。这就是为什么你必须使用你在OP中显示的某种Makefile.bat

侧注: VisualStudio或Windows SDK的特定版本取决于目标python版本。

答案 1 :(得分:2)

作为评论:在linux上,您可以使用许多autoconf环境变量。对于编译器

CC=mpicc python setup.py build_ext -i

答案 2 :(得分:0)

好吧,我发现了一个窍门:我想使用MSVC14.0(来自buildtools 2015)而不是MSVC14.1(buildtools 2017)。我编辑了文件Lib \ distutils_msvccompiler.py。有一种方法

_find_vcvarsall 

正在呼叫

best_version, best_dir = _find_vc2017()

我将此通话替换为

best_version, best_dir = _find_vc2015()

一旦编译,别忘了撤消这个肮脏的把戏。

答案 3 :(得分:0)

我最终将其放在setup.py的开头以强制visual2015

在非bat环境中运行并且从外部启动vcvarsall时不可用

if sys.platform == 'win32':
    # patch env with vcvarsall.bat from vs2015 (vc14)
    try:
        cmd = '"{}..\\..\\VC\\vcvarsall.bat" x86_amd64 >nul 2>&1 && set'.format(environ['VS140COMNTOOLS'])
        out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, universal_newlines=True)
    except:
        print("Error executing {}".format(cmd))
        raise

    for key, _, value in (line.partition('=') for line in out.splitlines()):
        if key and value:
            os.environ[key] = value

    # inform setuptools that the env is already set
    os.environ['DISTUTILS_USE_SDK'] = '1'