【问题标题】:Python distutils, how to get a compiler that is going to be used?Python distutils,如何获得将要使用的编译器?
【发布时间】:2010-10-18 00:03:14
【问题描述】:

例如,我可以使用python setup.py build --compiler=msvcpython setup.py build --compiler=mingw32 或仅使用python setup.py build,在这种情况下将使用默认编译器(例如bcpp)。如何在 setup.py 中获取编译器名称(例如,分别为 msvcmingw32bcpp)?

UPD.: 我不需要默认编译器,我需要的是实际要使用的编译器,不一定是默认编译器。到目前为止,我还没有找到比解析 sys.argv 以查看那里是否有 --compiler... 字符串更好的方法。

【问题讨论】:

  • 我也有同样的问题。我想为 msvc 包含一个额外的 stdint.h 标头,但不是其他编译器。

标签: python compiler-construction installation distutils


【解决方案1】:

导入 distutils.ccompiler

compiler_name = distutils.ccompiler.get_default_compiler()

【讨论】:

  • 这不一定是distutils要使用的编译器!
【解决方案2】:

您可以继承distutils.command.build_ext.build_ext 命令。

一旦调用build_ext.finalize_options() 方法,编译器类型将作为字符串存储在self.compiler.compiler_type 中(与传递给build_ext--compiler 选项的编译器类型相同,例如'mingw32'、'gcc '等...)。

【讨论】:

  • 编译器对象为self.compiler,类型在self.compiler.compiler_type
  • compiler_type 是在来自distutilsbuild_ext.run 方法中设置的。所以如果你有一个build_ext 子类并重写了run 方法,compiler_type 可能永远不会被设置。
【解决方案3】:
#This should work pretty good
def compilerName():
  import re
  import distutils.ccompiler
  comp = distutils.ccompiler.get_default_compiler()
  getnext = False

  for a in sys.argv[2:]:
    if getnext:
      comp = a
      getnext = False
      continue
    #separated by space
    if a == '--compiler'  or  re.search('^-[a-z]*c$', a):
      getnext = True
      continue
    #without space
    m = re.search('^--compiler=(.+)', a)
    if m == None:
      m = re.search('^-[a-z]*c(.+)', a)
    if m:
      comp = m.group(1)

  return comp


print "Using compiler " + '"' + compilerName() + '"'

【讨论】:

  • 这里不需要正则表达式,多次使用时需要编译。
【解决方案4】:

这是 Luper Rouch 答案的扩展版本,它帮助我获得了一个 openmp 扩展,以便在 Windows 上同时使用 mingw 和 msvc 进行编译。在子类化 build_ext 之后,您需要将其传递给 cmdclass arg 中的 setup.py。通过继承 build_extensions 而不是 finalize_options,您将拥有要查看的实际编译器对象,因此您可以获得更详细的版本信息。您最终可以在每个编译器、每个扩展的基础上设置编译器标志:

from distutils.core import setup, Extension
from distutils.command.build_ext import build_ext
copt =  {'msvc': ['/openmp', '/Ox', '/fp:fast','/favor:INTEL64','/Og']  ,
     'mingw32' : ['-fopenmp','-O3','-ffast-math','-march=native']       }
lopt =  {'mingw32' : ['-fopenmp'] }

class build_ext_subclass( build_ext ):
    def build_extensions(self):
        c = self.compiler.compiler_type
        if copt.has_key(c):
           for e in self.extensions:
               e.extra_compile_args = copt[ c ]
        if lopt.has_key(c):
            for e in self.extensions:
                e.extra_link_args = lopt[ c ]
        build_ext.build_extensions(self)

mod = Extension('_wripaca',
            sources=['../wripaca_wrap.c', 
                     '../../src/wripaca.c'],
            include_dirs=['../../include']
            )

setup (name = 'wripaca',
   ext_modules = [mod],
   py_modules = ["wripaca"],
   cmdclass = {'build_ext': build_ext_subclass } )

【讨论】:

  • 需要注意的是,对于 linux/posix 下的 gcc/clang,lopt 的键名必须是 'unix'
  • 谢谢。这些信息真的应该比这更容易获得。我们应该向 distutils 报告一个错误
【解决方案5】:
import sys
sys.argv.extend(['--compiler', 'msvc'])

【讨论】:

    【解决方案6】:
    class BuildWithDLLs(build):
    
        # On Windows, we install the git2.dll too.
        def _get_dlls(self):
            # return a list of of (FQ-in-name, relative-out-name) tuples.
            ret = []
            bld_ext = self.distribution.get_command_obj('build_ext')
            compiler_type = bld_ext.compiler.compiler_type
    

    您可以使用 self.distribution.get_command_obj('build_ext') 来获取 build_ext 实例, 然后得到compiler_type

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      • 2016-07-12
      • 2011-03-13
      • 2014-12-29
      • 1970-01-01
      相关资源
      最近更新 更多