运行python setup.py安装时强制编译器

运行python setup.py安装时强制编译器,python,cython,setuptools,anaconda,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(), cmdc

在运行
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和堆栈溢出答案

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安装
仍然使用conda附带的mingw编译器,而不是MS Windows SDK 7.1编译器

  • 因此,
    DISTUTILS\u USE\u SDK=1
    MSSdk=1
    似乎对楼宇没有影响。我不确定是否从conda virtualenv中激活MS SDK可能是一个问题

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

  • 还尝试运行
    %COMSPEC%/E:ON/V:ON/K”%PROGRAMFILES%\Microsoft SDK\Windows\v7.1\Bin\SetEnv.cmd“
    ,如上面链接的答案中所述,但对我来说,这会生成一个新的终端提示符,颜色为黄色,并停止安装过程

是否有一种方法可以强制编译器构建此包,例如,通过编辑
setup.py

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

[build]
compiler=msvc
现在调用
python setup.py build
相当于调用
python setup.py build--compiler=msvc
。(您仍然可以通过调用
python setup.py build--compiler=someothercompiler来指示distutils使用其他编译器

现在您已经(成功地)指示distutils使用msvc编译器。不幸的是,没有选项告诉它要使用哪个msvc编译器。基本上有两个选项:

One:不执行任何操作,distutils将尝试定位
vcvarsall.bat
,并使用它来设置环境。
vcvarsall.bat
(以及它为其设置环境的编译器)是Visual Studio的一部分,因此您必须安装它才能工作

2:安装Windows SDK并告诉distutils使用它。请注意,
Distils\u use\u SDK
的名称有点误导(至少在我看来)。它实际上并没有告诉distutils使用SDK(它是
setenv.bat
)要设置一个环境,相反,这意味着distutils应该假设环境已经设置好。这就是为什么您必须使用某种
Makefile.bat
,如您在OP中所示


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

注意:在linux上,您可以使用许多autoconf环境变量。对于编译器

CC=mpicc python setup.py build_ext -i

在我的例子中,我发现了一个窍门:我想使用MSVC14.0(来自buildtools 2015),而不是MSVC14.1(buildtools 2017)。我编辑了Lib\distutils\u msvccompiler.py文件。有一个方法

_find_vcvarsall 
哪个在呼叫

best_version, best_dir = _find_vc2017()
我把这个电话换成了

best_version, best_dir = _find_vc2015()

编译后不要忘了撤销这个肮脏的把戏。

我最后在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'

尝试使用
python setup.py build\u ext--compiler=msvc--force
强制编译器生成/重新生成包,看看会发生什么。@romeric因此
build\u ext
按照预期使用MS VC构建扩展(无论是否使用
--force
标志)。问题是,当我运行
安装程序时,它会用mingw重建。谢谢你的回答,在
安装程序.cfg
中指定编译器确实解决了Windows上的问题。问题是,简单地添加此文件也会破坏Linux上的安装,Linux上的安装程序应该使用gcc编译器,而不是MS VC。当然,这可能是对ge而言的在运行时生成
setup.cfg
,但我想知道是否有可能通过
setup.py
破解编译器选项,这将更加灵活…作为事后思考:我想,您可以根据自己的意愿破解distutils,毕竟我们这里讨论的是Python。目标点可能是
 build_ext
命令,如在“重新创建修改版本”或“派生修改现有版本”中。然而,我的印象是,整个distutils相当复杂(这可能源于事物的本质,是无法避免的)因此乍一看就很难理解。MS编译器的设置相当复杂,由于担心破坏向后兼容性(我的观点和猜测)
setup。cfg
是一个用户可以完全控制的文件。您不应该将其与代码一起分发。