How may I override the compiler (gcc) flags that setup.py uses by default?

I ran into this problem when I needed to fully remove a flag (-pipe) so I could compile SciPy on a low-memory system. I found that, as a hack, I could remove unwanted flags by editing /usr/lib/pythonN.N/_sysconfigdata.py to remove every instance of that flag, where N.N is your Python version. There are a lot of duplicates, and I'm not sure which are actually used by setup.py.


distutils/​setuptools allows any compiler/​linker flags to be specified with extra_compile_args/​extra_link_args argument when defining a Python extension in setup.py script. These extra flags will be added after default ones and will override any mutually exclusive flags present earlier.

For regular use, however, this is not much useful as a package you distribute through PyPI can be built by different compilers having an incompatible options.
The following code allows you to specify these options in extension- and compiler-specific way:

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},
    ...
)

Of course you could simplify it if you want all extensions to use the same (but still compiler-specific) options.

Here is a list of supported compiler types (as returned by 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

  • Prepend CFLAGS="-O0" before you run setup.py:

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

    The -O0 will be appended to CFLAGS while compiling, therefore will override previous -O2 setting.

  • Another way is add -O0 to extra_compile_args in setup.py:

    moduleA = Extension('moduleA', .....,
            include_dirs = ['/usr/include', '/usr/local/include'], 
            extra_compile_args = ["-O0"], 
            )
    
  • If you want to remove all default flags, use:

    % OPT="" python ./setup.py