176 lines
7.1 KiB
Python
176 lines
7.1 KiB
Python
"""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 (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
|
#
|
|
# 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__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/fortran.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
|
|
|
import re
|
|
import string
|
|
|
|
import SCons.Action
|
|
import SCons.Defaults
|
|
import SCons.Scanner.Fortran
|
|
import SCons.Tool
|
|
import SCons.Util
|
|
|
|
compilers = ['f95', 'f90', 'f77']
|
|
|
|
#
|
|
# 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(env.fs.File(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')
|
|
FortranCommandGenerator = VariableListGenerator('FORTRANCOM', 'F77COM', '_FORTRANCOMD')
|
|
FortranPPCommandGenerator = VariableListGenerator('FORTRANPPCOM', 'F77PPCOM', '_FORTRANPPCOMD')
|
|
ShFortranGenerator = VariableListGenerator('SHFORTRAN', 'SHF77', 'FORTRAN', 'F77', '_FORTRAND')
|
|
ShFortranFlagsGenerator = VariableListGenerator('SHFORTRANFLAGS', 'SHF77FLAGS')
|
|
ShFortranCommandGenerator = VariableListGenerator('SHFORTRANCOM', 'SHF77COM', '_SHFORTRANCOMD')
|
|
ShFortranPPCommandGenerator = VariableListGenerator('SHFORTRANPPCOM', 'SHF77PPCOM', '_SHFORTRANPPCOMD')
|
|
|
|
#
|
|
FortranAction = SCons.Action.Action('$_FORTRANCOMG ')
|
|
FortranPPAction = SCons.Action.Action('$_FORTRANPPCOMG ')
|
|
ShFortranAction = SCons.Action.Action('$_SHFORTRANCOMG ')
|
|
ShFortranPPAction = SCons.Action.Action('$_SHFORTRANPPCOMG ')
|
|
|
|
def add_to_env(env):
|
|
"""Add Builders and construction variables for Fortran to an Environment."""
|
|
|
|
env['_FORTRANG'] = FortranGenerator
|
|
env['_FORTRANFLAGSG'] = FortranFlagsGenerator
|
|
env['_FORTRANCOMG'] = FortranCommandGenerator
|
|
env['_FORTRANPPCOMG'] = FortranPPCommandGenerator
|
|
|
|
env['_SHFORTRANG'] = ShFortranGenerator
|
|
env['_SHFORTRANFLAGSG'] = ShFortranFlagsGenerator
|
|
env['_SHFORTRANCOMG'] = ShFortranCommandGenerator
|
|
env['_SHFORTRANPPCOMG'] = ShFortranPPCommandGenerator
|
|
|
|
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)
|
|
|
|
env['_FORTRANCOMD'] = '$_FORTRANG $_FORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
|
env['_FORTRANPPCOMD'] = '$_FORTRANG $_FORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
|
env['_SHFORTRANCOMD'] = '$_SHFORTRANG $_SHFORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
|
env['_SHFORTRANPPCOMD'] = '$_SHFORTRANG $_SHFORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
|
|
|
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)
|