2009-04-07 7 views
26

Ad esempio, è possibile utilizzare python setup.py build --compiler=msvc o python setup.py build --compiler=mingw32 o solo python setup.py build, nel qual caso verrà utilizzato il compilatore predefinito (ad esempio, bcpp). Come posso ottenere il nome del compilatore nel mio setup.py (per esempio msvc, mingw32 e bcpp, rispettivamente)?Distutils Python, come ottenere un compilatore che verrà utilizzato?

UPD .: Non ho bisogno del compilatore predefinito, ho bisogno di quello che è effettivamente, che non è necessariamente quello predefinito. Finora non ho trovato un modo migliore di analizzare parsing sys.argv per vedere se c'è una stringa --compiler... lì.

+0

Ho lo stesso problema. Voglio includere un'intestazione 'stdint.h' in più per msvc, ma non altri compilatori. –

risposta

0

importazione distutils.ccompiler

compiler_name = distutils.ccompiler.get_default_compiler()

+3

Questo non è necessariamente il compilatore che distutils sta per usare! – Jon

7

È possibile creare una sottoclasse il comando distutils.command.build_ext.build_ext.

volta build_ext.finalize_options() metodo è stato chiamato, il tipo compilatore viene memorizzato in self.compiler.compiler_type come stringa (lo stesso come quello passato al build_ext 'opzione s --compiler, es 'mingw32', 'gcc', ecc ...) .

+0

L'oggetto del compilatore è 'self.compiler', il tipo è in' self.compiler.compiler_type' –

+0

Modificato, grazie! –

1
 
#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() + '"' 
23

Questa è una versione ampliata della risposta di Luper Rouch che ha funzionato per me per ottenere una proroga OpenMP per compilare utilizzando sia MinGW e msvc sulle finestre. Dopo la sottoclasse di build_ext è necessario passarlo a setup.py nell'arg di cmdclass. Con la sottoclasse di build_extensions invece di finalize_options vedrai l'oggetto del compilatore da esaminare, in modo da poter ottenere informazioni più dettagliate sulla versione. Si potrebbe eventualmente impostare flag di compilazione su una base per-compilatore per-estensione:

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 }) 
+0

si noti che per gcc/clang sotto linux/posix il nome chiave per lopt deve essere 'unix' – marscher

+0

Grazie. L'informazione dovrebbe essere più accessibile di così. Dovremmo segnalare un bug alle distutils –

0
import sys 
sys.argv.extend(['--compiler', 'msvc']) 
0
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 

È possibile utilizzare self.distribution.get_command_obj ('build_ext') per ottenere build_ext esempio, e quindi ottieni il compiler_type