【问题标题】:How may I override the compiler (GCC) flags that setup.py uses by default?如何覆盖 setup.py 默认使用的编译器 (GCC) 标志?
【发布时间】:2011-10-19 04:16:09
【问题描述】:

我了解setup.py 使用与构建 Python 相同的CFLAGS。我有一个单独的 C 扩展,它是段错误的。我需要在没有 -O2 的情况下构建它,因为-O2 正在优化一些值和代码,因此核心文件不足以解决问题。

我只需要修改setup.py,使-O2不被使用。

我已阅读 distutils 文档,尤其是 distutils.ccompilerdistutils.unixccompiler 并了解如何添加标志和库以及包含,但不了解如何修改默认 GCC 标志。

具体来说,这是针对 Python 2.5.1 上的遗留产品,带有一堆反向端口(Fedora 8,是的,我知道......)。不,我无法更改操作系统或 Python 版本,并且我无法重新编译 Python。我只需要为一个环境是唯一一个段错误的客户构建一个 C 扩展。

【问题讨论】:

    标签: python gcc setuptools setup.py distutils


    【解决方案1】:
    • 在运行 setup.py 之前添加 CFLAGS="-O0"

      % CFLAGS="-O0" python ./setup.py
      

      编译时-O0 将附加到CFLAGS,因此将覆盖之前的-O2 设置。

    • 另一种方法是在setup.py 中添加-O0extra_compile_args

      moduleA = Extension('moduleA', .....,
              include_dirs = ['/usr/include', '/usr/local/include'], 
              extra_compile_args = ["-O0"], 
              )
      
    • 如果要删除所有默认标志,请使用:

      % OPT="" python ./setup.py
      

    【讨论】:

    • 当我使用上述设置运行时,它同时显示 CFlaGS、-O2 和 -O0。它没有覆盖它
    • @Sagar 对于 gcc 和 clang 等编译器,后面的标志优先,所以如果-O0 出现在-O2 之后的命令行中,那么-O0 将覆盖它。
    【解决方案2】:

    当我需要完全删除标志(-pipe)以便在低内存系统上编译 SciPy 时遇到了这个问题。我发现,作为 hack,我可以通过编辑 /usr/lib/pythonN.N/_sysconfigdata.py 来删除不需要的标志,以删除该标志的每个实例,其中 N.N 是您的 Python 版本。有很多重复,我不确定 setup.py 实际使用了哪些。

    【讨论】:

    • 这可以解决问题...只需编辑 CFLAGS 条目
    【解决方案3】:

    distutils/​setuptools 允许在 setup.py 脚本中定义 Python 扩展时使用 extra_compile_args/​extra_link_args 参数指定任何编译器/链接器标志。这些额外的标志将在默认标志之后添加,并将覆盖之前存在的任何互斥标志。

    但是,对于常规使用,这并没有多大用处,因为您通过 PyPI 分发的包可以由具有不兼容选项的不同编译器构建。
    以下代码允许您以扩展-和编译器-特定的方式指定这些选项:

    from setuptools import setup
    from setuptools.command.build_ext import build_ext
    
    
    class build_ext_ex(build_ext):
    
        extra_compile_args = {
            'extension_name': {
                'unix': ['-O0'],
                'msvc': ['/Od']
            }
        }
    
        def build_extension(self, ext):
            extra_args = self.extra_compile_args.get(ext.name)
            if extra_args is not None:
                ctype = self.compiler.compiler_type
                ext.extra_compile_args = extra_args.get(ctype, [])
    
            build_ext.build_extension(self, ext)
    
    
    setup(
        ...
        cmdclass = {'build_ext': build_ext_ex},
        ...
    )
    

    当然,如果您希望所有扩展都使用相同的(但仍是特定于编译器的)选项,您可以简化它。

    这是一个list of supported compiler types(由setup.py build_ext --help-compiler 返回):

    --compiler=bcpp     Borland C++ Compiler
    --compiler=cygwin   Cygwin port of GNU C Compiler for Win32
    --compiler=mingw32  Mingw32 port of GNU C Compiler for Win32
    --compiler=msvc     Microsoft Visual C++
    --compiler=unix     standard UNIX-style compiler
    

    【讨论】:

    • 它甚至兼容 Python 2.5。 =))
    猜你喜欢
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多