Get the commands distutils passes to the compiler

2019-04-23 13:18发布

Lets say I have this Python code in a setup.py script to build a C extension:

from distutils.core import setup, Extension

module1 = Extension('demo', sources = ['demo.c'])

setup (name = 'PackageName',
       version = '1.0',
       description = 'This is a demo package',
       ext_modules = [module1])

Easy enough. Now I call the setup.py script with this line:

C:/> python setup.py build_ext --compiler=mingw32

Ok, but whats the question?

When distutils calls mingw32 and passes all the necessary and operating system independant flags and options to it, how does it figure those flags out?

Where does distutils keep the commands related to each platform, and how can I access them?

1条回答
迷人小祖宗
2楼-- · 2019-04-23 13:53

It's not as simple as a set of options but you can see how it works. In your python source directory look for this

distutils/ccompiler.py

In that file each compiler has an entry like this

# Map compiler types to (module_name, class_name) pairs -- ie. where to
# find the code that implements an interface to this compiler.  (The module
# is assumed to be in the 'distutils' package.)
compiler_class = { 'unix':    ('unixccompiler', 'UnixCCompiler',
                               "standard UNIX-style compiler"),
                   'msvc':    ('msvccompiler', 'MSVCCompiler',
                               "Microsoft Visual C++"),
                   'cygwin':  ('cygwinccompiler', 'CygwinCCompiler',
                               "Cygwin port of GNU C Compiler for Win32"),
                   'mingw32': ('cygwinccompiler', 'Mingw32CCompiler',
                               "Mingw32 port of GNU C Compiler for Win32"),
                   'bcpp':    ('bcppcompiler', 'BCPPCompiler',
                               "Borland C++ Compiler"),
                   'emx':     ('emxccompiler', 'EMXCCompiler',
                               "EMX port of GNU C Compiler for OS/2"),
                 }    

You can find the code you're looking for in

distutils/cygwinccompiler.py

If you edit your setup.py script and add this

from distutils.core import setup,Extension
from distutils.cygwinccompiler import Mingw32CCompiler
from pprint import pprint

module1 = Extension('demo', sources = ['demo.c'])

m32 = Mingw32CCompiler()
pprint (vars(m32))


setup (name = 'PackageName',
   version = '1.0',
   description = 'This is a demo package',
   ext_modules = [module1])

You can see quite a few of the options available...

{'archiver': ['ar', '-cr'],
 'compiler': ['gcc', '-O', '-Wall'],
 'compiler_cxx': ['g++', '-O', '-Wall'],
 'compiler_so': ['gcc', '-mdll', '-O', '-Wall'],
 'dll_libraries': None,
 'dllwrap_version': None,
 'dry_run': 0,
 'force': 0,
 'gcc_version': LooseVersion ('4.2.1'),
 'include_dirs': [],
 'ld_version': None,
 'libraries': [],
 'library_dirs': [],
 'linker_dll': 'dllwrap',
 'linker_exe': ['gcc'],
 'linker_so': ['dllwrap', '-mdll', '-static'],
 'macros': [],
 'objects': [],
 'output_dir': None,
 'preprocessor': None,
 'ranlib': ['ranlib'],
 'runtime_library_dirs': [],
 'verbose': 0}

To access individual options you can use them as follows...

print m32.compile
['gcc', '-O', '-Wall']

There's no simple set of flags. A lot of the flags are configured at runtime and the code above shows you were to look to see how they're generated etc.

查看更多
登录 后发表回答