FortranCommon.py
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:9k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. """SCons.Tool.FortranCommon
  2. Stuff for processing Fortran, common to all fortran dialects.
  3. """
  4. #
  5. # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining
  8. # a copy of this software and associated documentation files (the
  9. # "Software"), to deal in the Software without restriction, including
  10. # without limitation the rights to use, copy, modify, merge, publish,
  11. # distribute, sublicense, and/or sell copies of the Software, and to
  12. # permit persons to whom the Software is furnished to do so, subject to
  13. # the following conditions:
  14. #
  15. # The above copyright notice and this permission notice shall be included
  16. # in all copies or substantial portions of the Software.
  17. #
  18. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
  19. # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  20. # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  22. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. #
  26. __revision__ = "src/engine/SCons/Tool/FortranCommon.py 3057 2008/06/09 22:21:00 knight"
  27. import re
  28. import string
  29. import os.path
  30. import SCons.Action
  31. import SCons.Defaults
  32. import SCons.Scanner.Fortran
  33. import SCons.Tool
  34. import SCons.Util
  35. def isfortran(env, source):
  36.     """Return 1 if any of code in source has fortran files in it, 0
  37.     otherwise."""
  38.     try:
  39.         fsuffixes = env['FORTRANSUFFIXES']
  40.     except KeyError:
  41.         # If no FORTRANSUFFIXES, no fortran tool, so there is no need to look
  42.         # for fortran sources.
  43.         return 0
  44.     if not source:
  45.         # Source might be None for unusual cases like SConf.
  46.         return 0
  47.     for s in source:
  48.         if s.sources:
  49.             ext = os.path.splitext(str(s.sources[0]))[1]
  50.             if ext in fsuffixes:
  51.                 return 1
  52.     return 0
  53. def _fortranEmitter(target, source, env):
  54.     node = source[0].rfile()
  55.     if not node.exists() and not node.is_derived():
  56.        print "Could not locate " + str(node.name)
  57.        return ([], [])
  58.     mod_regex = """(?i)^s*MODULEs+(?!PROCEDURE)(w+)"""
  59.     cre = re.compile(mod_regex,re.M)
  60.     # Retrieve all USE'd module names
  61.     modules = cre.findall(node.get_contents())
  62.     # Remove unique items from the list
  63.     modules = SCons.Util.unique(modules)
  64.     # Convert module name to a .mod filename
  65.     suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source)
  66.     moddir = env.subst('$FORTRANMODDIR', target=target, source=source)
  67.     modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
  68.     for m in modules:
  69.        target.append(env.fs.File(m, moddir))
  70.     return (target, source)
  71. def FortranEmitter(target, source, env):
  72.     target, source = _fortranEmitter(target, source, env)
  73.     return SCons.Defaults.StaticObjectEmitter(target, source, env)
  74. def ShFortranEmitter(target, source, env):
  75.     target, source = _fortranEmitter(target, source, env)
  76.     return SCons.Defaults.SharedObjectEmitter(target, source, env)
  77. def ComputeFortranSuffixes(suffixes, ppsuffixes):
  78.     """suffixes are fortran source files, and ppsuffixes the ones to be
  79.     pre-processed. Both should be sequences, not strings."""
  80.     assert len(suffixes) > 0
  81.     s = suffixes[0]
  82.     sup = string.upper(s)
  83.     upper_suffixes = map(string.upper, suffixes)
  84.     if SCons.Util.case_sensitive_suffixes(s, sup):
  85.         ppsuffixes.extend(upper_suffixes)
  86.     else:
  87.         suffixes.extend(upper_suffixes)
  88. def CreateDialectActions(dialect):
  89.     """Create dialect specific actions."""
  90.     CompAction = SCons.Action.Action('$%sCOM ' % dialect, '$%sCOMSTR' % dialect)
  91.     CompPPAction = SCons.Action.Action('$%sPPCOM ' % dialect, '$%sPPCOMSTR' % dialect)
  92.     ShCompAction = SCons.Action.Action('$SH%sCOM ' % dialect, '$SH%sCOMSTR' % dialect)
  93.     ShCompPPAction = SCons.Action.Action('$SH%sPPCOM ' % dialect, '$SH%sPPCOMSTR' % dialect)
  94.     return CompAction, CompPPAction, ShCompAction, ShCompPPAction
  95. def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_module = 0):
  96.     """Add dialect specific construction variables."""
  97.     ComputeFortranSuffixes(suffixes, ppsuffixes)
  98.     fscan = SCons.Scanner.Fortran.FortranScan("%sPATH" % dialect)
  99.     for suffix in suffixes + ppsuffixes:
  100.         SCons.Tool.SourceFileScanner.add_scanner(suffix, fscan)
  101.     env.AppendUnique(FORTRANSUFFIXES = suffixes + ppsuffixes)
  102.     compaction, compppaction, shcompaction, shcompppaction = 
  103.             CreateDialectActions(dialect)
  104.     static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
  105.     for suffix in suffixes:
  106.         static_obj.add_action(suffix, compaction)
  107.         shared_obj.add_action(suffix, shcompaction)
  108.         static_obj.add_emitter(suffix, FortranEmitter)
  109.         shared_obj.add_emitter(suffix, ShFortranEmitter)
  110.     for suffix in ppsuffixes:
  111.         static_obj.add_action(suffix, compppaction)
  112.         shared_obj.add_action(suffix, shcompppaction)
  113.         static_obj.add_emitter(suffix, FortranEmitter)
  114.         shared_obj.add_emitter(suffix, ShFortranEmitter)
  115.     if not env.has_key('%sFLAGS' % dialect):
  116.         env['%sFLAGS' % dialect] = SCons.Util.CLVar('')
  117.     if not env.has_key('SH%sFLAGS' % dialect):
  118.         env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect)
  119.     # If a tool does not define fortran prefix/suffix for include path, use C ones
  120.     if not env.has_key('INC%sPREFIX' % dialect):
  121.         env['INC%sPREFIX' % dialect] = '$INCPREFIX'
  122.     if not env.has_key('INC%sSUFFIX' % dialect):
  123.         env['INC%sSUFFIX' % dialect] = '$INCSUFFIX'
  124.     env['_%sINCFLAGS' % dialect] = '$( ${_concat(INC%sPREFIX, %sPATH, INC%sSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' % (dialect, dialect, dialect)
  125.     if support_module == 1:
  126.         env['%sCOM' % dialect]     = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect)
  127.         env['%sPPCOM' % dialect]   = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect)
  128.         env['SH%sCOM' % dialect]    = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect)
  129.         env['SH%sPPCOM' % dialect]  = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect)
  130.     else:
  131.         env['%sCOM' % dialect]     = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect)
  132.         env['%sPPCOM' % dialect]   = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect)
  133.         env['SH%sCOM' % dialect]    = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect)
  134.         env['SH%sPPCOM' % dialect]  = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect)
  135. def add_fortran_to_env(env):
  136.     """Add Builders and construction variables for Fortran to an Environment."""
  137.     try:
  138.         FortranSuffixes = env['FORTRANFILESUFFIXES']
  139.     except KeyError:
  140.         FortranSuffixes = ['.f', '.for', '.ftn']
  141.     #print "Adding %s to fortran suffixes" % FortranSuffixes
  142.     try:
  143.         FortranPPSuffixes = env['FORTRANPPFILESUFFIXES']
  144.     except KeyError:
  145.         FortranPPSuffixes = ['.fpp', '.FPP']
  146.     DialectAddToEnv(env, "FORTRAN", FortranSuffixes,
  147.                     FortranPPSuffixes, support_module = 1)
  148.     env['FORTRANMODPREFIX'] = ''     # like $LIBPREFIX
  149.     env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX
  150.     env['FORTRANMODDIR'] = ''          # where the compiler should place .mod files
  151.     env['FORTRANMODDIRPREFIX'] = ''    # some prefix to $FORTRANMODDIR - similar to $INCPREFIX
  152.     env['FORTRANMODDIRSUFFIX'] = ''    # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX
  153.     env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
  154. def add_f77_to_env(env):
  155.     """Add Builders and construction variables for f77 to an Environment."""
  156.     try:
  157.         F77Suffixes = env['F77FILESUFFIXES']
  158.     except KeyError:
  159.         F77Suffixes = ['.f77']
  160.     #print "Adding %s to f77 suffixes" % F77Suffixes
  161.     try:
  162.         F77PPSuffixes = env['F77PPFILESUFFIXES']
  163.     except KeyError:
  164.         F77PPSuffixes = []
  165.     DialectAddToEnv(env, "F77", F77Suffixes, F77PPSuffixes)
  166. def add_f90_to_env(env):
  167.     """Add Builders and construction variables for f90 to an Environment."""
  168.     try:
  169.         F90Suffixes = env['F90FILESUFFIXES']
  170.     except KeyError:
  171.         F90Suffixes = ['.f90']
  172.     #print "Adding %s to f90 suffixes" % F90Suffixes
  173.     try:
  174.         F90PPSuffixes = env['F90PPFILESUFFIXES']
  175.     except KeyError:
  176.         F90PPSuffixes = []
  177.     DialectAddToEnv(env, "F90", F90Suffixes, F90PPSuffixes,
  178.                     support_module = 1)
  179. def add_f95_to_env(env):
  180.     """Add Builders and construction variables for f95 to an Environment."""
  181.     try:
  182.         F95Suffixes = env['F95FILESUFFIXES']
  183.     except KeyError:
  184.         F95Suffixes = ['.f95']
  185.     #print "Adding %s to f95 suffixes" % F95Suffixes
  186.     try:
  187.         F95PPSuffixes = env['F95PPFILESUFFIXES']
  188.     except KeyError:
  189.         F95PPSuffixes = []
  190.     DialectAddToEnv(env, "F95", F95Suffixes, F95PPSuffixes,
  191.                     support_module = 1)
  192. def add_all_to_env(env):
  193.     """Add builders and construction variables for all supported fortran
  194.     dialects."""
  195.     add_fortran_to_env(env)
  196.     add_f77_to_env(env)
  197.     add_f90_to_env(env)
  198.     add_f95_to_env(env)