diff options
author | Steven Knight <knight@baldmt.com> | 2004-07-29 13:22:43 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2004-07-29 13:22:43 (GMT) |
commit | 39c71db4a22f03bf17a39fa84ff6abe84e4f0d51 (patch) | |
tree | 26e7f0319f29604b9c80df73009b768d1f0067a6 /src/engine/SCons/Tool/fortran.py | |
parent | 6a1ff461cdea7e26330ebcdce821ae5a95e415ce (diff) | |
download | SCons-39c71db4a22f03bf17a39fa84ff6abe84e4f0d51.zip SCons-39c71db4a22f03bf17a39fa84ff6abe84e4f0d51.tar.gz SCons-39c71db4a22f03bf17a39fa84ff6abe84e4f0d51.tar.bz2 |
Add Fortran 90/95 support. (Chris Murray)
Diffstat (limited to 'src/engine/SCons/Tool/fortran.py')
-rw-r--r-- | src/engine/SCons/Tool/fortran.py | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/src/engine/SCons/Tool/fortran.py b/src/engine/SCons/Tool/fortran.py new file mode 100644 index 0000000..5e2b5eb --- /dev/null +++ b/src/engine/SCons/Tool/fortran.py @@ -0,0 +1,165 @@ +"""SCons.Tool.fortran + +Tool-specific initialization for a generic Posix f77/f90 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import re +import string + +import SCons.Action +import SCons.Defaults +import SCons.Scanner.Fortran +import SCons.Tool +import SCons.Util + +compilers = ['f95', 'f90', 'f77'] + +FortranAction = SCons.Action.Action("$FORTRANCOM") +ShFortranAction = SCons.Action.Action("$SHFORTRANCOM") +FortranPPAction = SCons.Action.Action("$FORTRANPPCOM") +ShFortranPPAction = SCons.Action.Action("$SHFORTRANPPCOM") + +# +# Not yet sure how to deal with fortran pre-processor functions. +# Different compilers do this differently in modern fortran. Some still +# rely on the c pre-processor, some (like cvf, ivf) have their own +# pre-processor technology and use intermediary suffixes (.i90) +# +FortranSuffixes = [".f", ".for", ".ftn", ] +FortranPPSuffixes = ['.fpp', '.FPP'] +upper_case = [".F", ".FOR", ".FTN"] +if SCons.Util.case_sensitive_suffixes('.f', '.F'): + FortranPPSuffixes.extend(upper_case) +else: + FortranSuffixes.extend(upper_case) + +# +FortranScan = SCons.Scanner.Fortran.FortranScan("FORTRANPATH") + +for suffix in FortranSuffixes + FortranPPSuffixes: + SCons.Defaults.ObjSourceScan.add_scanner(suffix, FortranScan) + +# +def _fortranEmitter(target, source, env): + node = source[0].rfile() + if not node.exists() and not node.is_derived(): + print "Could not locate " + str(node.name) + return ([], []) + mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)""" + cre = re.compile(mod_regex,re.M) + # Retrieve all USE'd module names + modules = cre.findall(node.get_contents()) + # Remove unique items from the list + modules = SCons.Util.unique(modules) + # Convert module name to a .mod filename + suffix = env.subst('$FORTRANMODSUFFIX') + modules = map(lambda x, s=suffix: string.lower(x) + s, modules) + for m in modules: + target.append(m) + return (target, source) + +def FortranEmitter(target, source, env): + target, source = _fortranEmitter(target, source, env) + return SCons.Defaults.StaticObjectEmitter(target, source, env) + +def ShFortranEmitter(target, source, env): + target, source = _fortranEmitter(target, source, env) + return SCons.Defaults.SharedObjectEmitter(target, source, env) + +class VariableListGenerator: + def __init__(self, *variablelist): + self.variablelist = variablelist + def __call__(self, env, target, source, for_signature): + for v in self.variablelist: + try: return env[v] + except KeyError: pass + return '' + +FortranGenerator = VariableListGenerator('FORTRAN', 'F77', '_FORTRAND') +FortranFlagsGenerator = VariableListGenerator('FORTRANFLAGS', 'F77FLAGS') +ShFortranGenerator = VariableListGenerator('SHFORTRAN', 'SHF77', 'FORTRAN', 'F77', '_FORTRAND') +ShFortranFlagsGenerator = VariableListGenerator('SHFORTRANFLAGS', 'SHF77FLAGS') + +def add_to_env(env): + """Add Builders and construction variables for Fortran to an Environment.""" + + env['_FORTRANG'] = FortranGenerator + env['_FORTRANFLAGSG'] = FortranFlagsGenerator + env['FORTRANCOM'] = '$_FORTRANG $_FORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES' + env['FORTRANPPCOM'] = '$_FORTRANG $_FORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES' + + env['_SHFORTRANG'] = ShFortranGenerator + env['_SHFORTRANFLAGSG'] = ShFortranFlagsGenerator + env['SHFORTRANCOM'] = '$_SHFORTRANG $_SHFORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES' + env['SHFORTRANPPCOM'] = '$_SHFORTRANG $_SHFORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES' + + env['_FORTRANINCFLAGS'] = '$( ${_concat(INCPREFIX, FORTRANPATH, INCSUFFIX, __env__, RDirs)} $)' + + env['FORTRANMODPREFIX'] = '' # like $LIBPREFIX + env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX + + env['FORTRANMODDIR'] = '' # where the compiler should place .mod files + env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX + env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX + env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__)} $)' + + env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes) + + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in FortranSuffixes: + static_obj.add_action(suffix, FortranAction) + shared_obj.add_action(suffix, ShFortranAction) + static_obj.add_emitter(suffix, FortranEmitter) + shared_obj.add_emitter(suffix, ShFortranEmitter) + + for suffix in FortranPPSuffixes: + static_obj.add_action(suffix, FortranPPAction) + shared_obj.add_action(suffix, ShFortranPPAction) + static_obj.add_emitter(suffix, FortranEmitter) + shared_obj.add_emitter(suffix, ShFortranEmitter) + +def generate(env): + import f77 + import f90 + import f95 + f77.add_to_env(env) + f90.add_to_env(env) + f95.add_to_env(env) + + add_to_env(env) + + env['_FORTRAND'] = env.Detect(compilers) or 'f77' + +def exists(env): + return env.Detect(compilers) |