2013-04-26 4 views
5

Eine gängige Methode zum Erstellen von Quellcode auf * NIX-Plattformen ist die Verwendung eines configure-Skripts. Unter der Haube versucht configure, eine Reihe von Testprogrammen zu erstellen, um festzustellen, auf welche Bibliotheken Sie zugreifen können. Es erzeugt dann eine Headerdatei, die in das Projekt aufgenommen wird, das eine Reihe von Makros bedingt definiert, so dass der Programmierer eine Alternative bereitstellen oder eine abgespeckte Version einer Bibliothek/eines Programms erstellen kann, wenn eine bestimmte "Abhängigkeit" fehlt. Gibt es eine funktional äquivalente Verwendung von ?numpy distutils - Versuchen Sie, etwas zu kompilieren und Flags zu setzen, wenn Sie fehlschlagen

Als Beispiel ist hier mein setup.py:

from numpy.distutils.misc_util import Configuration 

def configuration(parent_package='',top_path=None): 
    config = Configuration('pyggcm',parent_package,top_path) 

    #TODO: Currently, I have some macros to conditionally build the seek-code 
    #Unfortunately, that's not the best solution (by far). Perhaps if we 
    #changed to using stream access it would work better, without the need 
    #for these silly macros. 
    config.add_extension('_fortfile',sources=['_fortfile/_fortfile.F90'], 
         define_macros=[ 
          ('FSEEKABLE',1), #compiler provides fseek and ftell 
          ('HAVE_STREAM',1) #compiler provides access='stream' for opening files. (f2003 standard) 
          ]) 

    config.add_extension('jrrle',sources=['jrrle/jrrle.f90']) 
    config.add_scripts(['scripts/ggcm_timehist', 
         'scripts/ggcm_plasmasheet', 
         'scripts/ggcm_plot']) 
    return config 


from numpy.distutils.core import setup  
setup(configuration=configuration) 

Dieses bedingungslos baut die FSEEKABLE Code und müssten manuell, wenn der Fortran-Compiler, der (Die Makros wickeln die fseek nicht unterstützt Benutzer bearbeitet werden und ftell GNU intrinsische Funktion). Gibt es eine Möglichkeit festzustellen, ob der Fortran-Compiler diese intrinsischen Funktionen liefert?

Antwort

0

Generieren Sie ein Codefragment in eine Datei & versuchen Sie es zu kompilieren, die Überprüfung der Fehlercodes ist der normale Ansatz und sollte gut funktionieren - aber AFAIK niemand hat dies bereits für Sie als Teil von distutils getan. Ich vermute, dass einer der anderen, möglicherweise Python-basierten, Werkzeuge wie diese unterstützt. Ich denke, dass deine beste Wette GNU-Autokonfiguration ist.

+0

Fehlende Wort: * ... Build-Tools wie kann ... *? – Tshepang

1

Versuchen Sie folgendes:

import os 
import shutil 
import tempfile 
from distutils.ccompiler import new_compiler 

def hasfunction(cc, funcname, include=None, extra_postargs=None): 
    tmpdir = tempfile.mkdtemp(prefix='hasfunction-') 
    devnull = oldstderr = None 
    try: 
     try: 
      fname = os.path.join(tmpdir, 'funcname.c') 
      f = open(fname, 'w') 
      if include is not None: 
       f.write('#include %s\n' % include) 
      f.write('int main(void) {\n') 
      f.write(' %s;\n' % funcname) 
      f.write('}\n') 
      f.close() 
      devnull = open(os.devnull, 'w') 
      oldstderr = os.dup(sys.stderr.fileno()) 
      os.dup2(devnull.fileno(), sys.stderr.fileno()) 
      objects = cc.compile([fname], output_dir=tmpdir, 
           extra_postargs=extra_postargs) 
      cc.link_executable(objects, os.path.join(tmpdir, 'a.out')) 
     except Exception as e: 
      return False 
     return True 
    finally: 
     if oldstderr is not None: 
      os.dup2(oldstderr, sys.stderr.fileno()) 
     if devnull is not None: 
      devnull.close() 
     shutil.rmtree(tmpdir) 

Beispiel:

def detect_sse3(): 
    "Does this compiler support SSE3 intrinsics?" 
    compiler = new_compiler() 
    return hasfunction(compiler, '__m128 v; _mm_hadd_ps(v,v)', 
         include='<pmmintrin.h>', 
         extra_postargs=['-msse3'])