125 lines
4.2 KiB
Python
125 lines
4.2 KiB
Python
import os
|
|
import subprocess
|
|
import datetime
|
|
from pkg_resources import parse_version
|
|
from setuptools_scm import get_version
|
|
|
|
###############################################################################
|
|
def filtered_glob(env, pattern, omit=[],
|
|
ondisk=True, source=False, strings=False):
|
|
return list(filter(
|
|
lambda f: os.path.basename(f.path) not in omit,
|
|
env.Glob(pattern)))
|
|
|
|
# Create a builder for f2py
|
|
def f2py_generator(source, target, env, for_signature):
|
|
suffix = ".so"
|
|
main = source[0]
|
|
objects = " ".join(o.get_path() for o in source[1:] if str(o).endswith('.o'))
|
|
moduledir = os.path.dirname(target[0].abspath)
|
|
modulefile = str(target[0])
|
|
modulename = modulefile.replace(suffix, '').replace('/', '.')
|
|
compiler = env['FORTRAN']
|
|
|
|
cmd = f"$F2PY --fcompiler={compiler} "
|
|
cmd += f" $F2PY_OPTS -m {modulename} -c {objects} {main}"
|
|
cmd += f" && cp {'/'.join(modulename.split('.'))}.*.so {modulefile}"
|
|
#cmd += " 1>/dev/null 2>/dev/null"
|
|
return cmd
|
|
|
|
def install_module(env, module):
|
|
destdir = os.path.dirname(module[0].srcnode().abspath)
|
|
env.Install(destdir, module)
|
|
env.Alias('install', destdir)
|
|
return None
|
|
|
|
def version_action(target, source, env):
|
|
with open(str(target[0]), 'w') as fd:
|
|
v = get_version(root='../', relative_to='./', version_scheme="post-release")
|
|
v = parse_version(v)
|
|
if v._version.post[-1] == 0:
|
|
version = v.base_version
|
|
else:
|
|
version = v.public
|
|
fd.write(version + '\n')
|
|
now = datetime.datetime.now().isoformat()
|
|
fd.write(f'compiled on {now}\n')
|
|
p = subprocess.run([env['FORTRAN'], "--version"], stdout=subprocess.PIPE)
|
|
fd.write(p.stdout.decode('utf8'))
|
|
|
|
|
|
f2py_bld = Builder(generator=f2py_generator)
|
|
version_bld = Builder(action=version_action)
|
|
|
|
# define the default build environment
|
|
std = Environment(tools=['default', 'fortran'], F2PY_OPTS=[], LIBS=[])
|
|
std.AddMethod(filtered_glob, "FilteredGlob")
|
|
std.AddMethod(install_module, "InstallModule")
|
|
std['BUILDERS']['F2py'] = f2py_bld
|
|
std['BUILDERS']['Version'] = version_bld
|
|
|
|
###############################################################################
|
|
|
|
# Define the command line options
|
|
AddOption('--dbg',
|
|
dest='dbg',
|
|
action='store_true',
|
|
help='add debugging symbols')
|
|
|
|
AddOption('--verbose',
|
|
dest='verbose',
|
|
action='store_true',
|
|
help='add debugging symbols')
|
|
|
|
AddOption('--compiler',
|
|
dest='compiler',
|
|
default='gfortran',
|
|
choices=['gfortran', 'ifort'],
|
|
help='The Fortran compiler to use')
|
|
|
|
AddOption('--f2py_path',
|
|
dest='f2py_path',
|
|
default='f2py3',
|
|
help='The full path to the f2py compiler')
|
|
|
|
|
|
|
|
# define environments
|
|
gfortran_env = std.Clone(tools=['gfortran'])
|
|
#gfortran_env.Replace(FORTRANFLAGS=['-fPIC', '-O2', '-ffast-math', '-mcmodel=large', '-fdefault-real-8', '-fdefault-double-8'])
|
|
gfortran_env.Replace(FORTRANFLAGS=['-fPIC', '-mcmodel=large'])
|
|
|
|
ifort_env = std.Clone(tools=['ifort'])
|
|
|
|
# parse options
|
|
if GetOption('compiler') == 'gfortran':
|
|
env = gfortran_env
|
|
#env.Append(F2PY_OPTS='--opt=-O2')
|
|
elif GetOption('compiler') == 'ifort':
|
|
env = ifort_env
|
|
|
|
f2py_path = GetOption('f2py_path')
|
|
p = subprocess.run(['which', f2py_path], stdout=subprocess.PIPE)
|
|
if p.returncode != 0:
|
|
raise Exception('Invalid path for f2py compiler!')
|
|
else:
|
|
env.Append(F2PY=p.stdout.decode('utf8').strip())
|
|
|
|
if GetOption('dbg'):
|
|
gfortran_env.Append(FORTRANFLAGS = ['-g', '-Wall', '-Wextra', '-Warray-temporaries',
|
|
'-Wconversion', '-fbacktrace', '-ffree-line-length-0',
|
|
'-fcheck=all', '-ffpe-trap=zero,overflow,underflow,invalid,denormal',
|
|
'-finit-real=nan'],
|
|
F2PY_OPTS = ['--noopt', '--debug-capi', '--debug'])
|
|
|
|
if GetOption('verbose'):
|
|
env.Replace(FORTRANCOMSTR = "")
|
|
|
|
|
|
Export('env')
|
|
SConscript('msspec/spec/fortran/SConstruct', variant_dir='build/build_spec')
|
|
SConscript('msspec/phagen/fortran/SConstruct', variant_dir='build/build_phagen')
|
|
|
|
version_file = env.Version('VERSION', [])
|
|
Depends(version_file, "install")
|