diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000..9545e5d --- /dev/null +++ b/SConstruct @@ -0,0 +1,94 @@ +from sysconfig import get_config_var +import os + +# 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') + +def CheckPKGConfig(context, version): + context.Message( 'Checking for pkg-config... ' ) + ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0] + context.Result( ret ) + return ret + +def CheckPKG(context, name): + context.Message( 'Checking for %s... ' % name ) + ret = context.TryAction('pkg-config --exists \'%s\'' % name)[0] + context.Result( ret ) + return ret + +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))) + + + +# define the default build environment +std = Environment(tools=['default', 'fortran'], F2PY_OPTS=[], FORTRANCOMSTR = "building $TARGET ...", LIBS=[]) +std.AddMethod(filtered_glob, "FilteredGlob"); + +# define environments +gfortran_env = std.Clone(tools=['gfortran']) +gfortran_env.Replace(FORTRANFLAGS=['-fPIC', '-O2', '-ffast-math', '-fno-automatic']) + +ifort_env = std.Clone(tools=['ifort']) + +# parse options +if GetOption('compiler') == 'gfortran': + env = gfortran_env +elif GetOption('compiler') == 'ifort': + env = ifort_env + +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', + '-finit-real=nan'], + F2PY_OPTS = ['--debug-capi', '--debug']) + +if GetOption('verbose'): + env.Replace(FORTRANCOMSTR = "") + + +conf = Configure(env, custom_tests = { 'CheckPKG' : CheckPKG}) +suffix = get_config_var('EXT_SUFFIX') + +# Create a builder for f2py +def create_f2py_cmd(source, target, env, for_signature): + objects = source[1:] + cmd = "f2py3 " + cmd += " ".join([o.get_path() for o in objects if str(o).endswith('o')]) + cmd += f" $F2PY_OPTS -m {str(target[0]).replace(suffix,'').replace('/', '.')} -c {source[0]}" + return cmd + +def modify_targets(target, source, env): + target[0] = str(target[0]) + suffix + #print(target[0]) + return target, source + +bld = Builder(generator=create_f2py_cmd, emitter = modify_targets) +env['BUILDERS']['F2PY'] = bld + + + +# exports +Export('env', 'conf') + + +SConscript(['src/msspec/spec/fortran/SConstruct', + 'src/msspec/phagen/fortran/SConstruct']) diff --git a/src/msspec/phagen/fortran/SConstruct b/src/msspec/phagen/fortran/SConstruct new file mode 100644 index 0000000..7b389d8 --- /dev/null +++ b/src/msspec/phagen/fortran/SConstruct @@ -0,0 +1,16 @@ + +try: + Import('env') +except: + SConscript(['../../../../SConstruct']) +finally: + Import('env') + + +objects_src= ['phagen_scf_2.1_dp.f'] +objects = env.Object(objects_src) + +module = env.F2PY('libphagen', ['main.f'] + objects) +Requires(module, objects) + +env.Alias('phagen', module) diff --git a/src/msspec/spec/fortran/SConstruct b/src/msspec/spec/fortran/SConstruct index 53ba2c0..5b0e405 100644 --- a/src/msspec/spec/fortran/SConstruct +++ b/src/msspec/spec/fortran/SConstruct @@ -1,111 +1,77 @@ -from sysconfig import get_config_var -import os - -# 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') - -def CheckPKGConfig(context, version): - context.Message( 'Checking for pkg-config... ' ) - ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0] - context.Result( ret ) - return ret - -def CheckPKG(context, name): - context.Message( 'Checking for %s... ' % name ) - ret = context.TryAction('pkg-config --exists \'%s\'' % name)[0] - context.Result( ret ) - return ret - - - - -# define environments -std = Environment(tools=['default', 'fortran'], F2PY_OPTS=[], FORTRANCOMSTR = "building $TARGET ...") - -gfortran_env = std.Clone(tools=['gfortran']) -gfortran_env.Replace(FORTRANFLAGS=['-fPIC', '-O2', '-ffast-math', '-fno-automatic']) - -ifort_env = std.Clone(tools=['ifort']) - -# parse options -if GetOption('compiler') == 'gfortran': - env = gfortran_env -elif GetOption('compiler') == 'ifort': - env = ifort_env - -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', - '-finit-real=nan'], - F2PY_OPTS = ['--debug-capi', '--debug']) - -if GetOption('verbose'): - env.Replace(FORTRANCOMSTR = "") +# imports +try: + Import('env', 'conf') +except: + SConscript(['../../../../SConstruct']) +finally: + Import('env', 'conf') # Configuration: -conf = Configure(env, custom_tests = { 'CheckPKG' : CheckPKG}) - if conf.CheckPKG('lapack'): - env.ParseConfig("pkg-config lapack --libs") - + env.ParseConfig("pkg-config lapack --libs") conf.Finish() +dir = Dir('.').get_abspath() +env.Append(FORTRANFLAGS=['-I' + dir,'-J' + dir]) +env.Append(F2PY_OPTS=['-I' + dir]) -suffix = get_config_var('EXT_SUFFIX') +# define sources +dim_mod = ['memalloc/dim_mod.f'] +memalloc = ['memalloc/modules.f', 'memalloc/allocation.f'] +cluster_gen = Glob('cluster_gen/*.f') +common_sub = Glob('common_sub/*.f') +renormalization = Glob('renormalization/*.f') +phd_se_noso_nosp_nosym = env.FilteredGlob('phd_se_noso_nosp_nosym/*.f', omit=['main.f']) +phd_mi_noso_nosp_nosym = env.FilteredGlob('phd_mi_noso_nosp_nosym/*.f', omit=['main.f']) +eig_common = Glob('eig/common/*.f') +eig_mi = env.FilteredGlob('eig/mi/*.f', omit=['main.f']) +eig_pw = env.FilteredGlob('eig/pw/*.f', omit=['main.f']) -sources = { - 'dim_mod_src' : ['memalloc/dim_mod.f'], - 'memalloc_src' : ['memalloc/modules.f', 'memalloc/allocation.f'], - 'cluster_gen_src' : Glob('cluster_gen/*.f'), - 'common_sub_src' : Glob('common_sub/*.f'), - 'renormalization_src' : Glob('renormalization/*.f'), - 'phd_se_noso_nosp_nosym_src': Glob('phd_se_noso_nosp_nosym/*.f'), - 'phd_mi_noso_nosp_nosym_src': Glob('phd_mi_noso_nosp_nosym/*.f'), - 'eig_common_src' : Glob('eig/common/*.f'), - 'eig_mi_src' : Glob('eig/mi/*.f'), - 'eig_pw_src' : Glob('eig/pw/*.f')} + +#for f in eig_mi: +# print(f) +#exit() if 'lapack' in env['LIBS']: - env.Append(F2PY_OPTS = "-llapack") - for k,files in sources.items(): - sources[k] = [_ for _ in files if str(_).find('lapack') == -1] + env.Append(F2PY_OPTS = "-llapack") + eig_mi = [f for f in eig_mi if str(f).find('lapack') == -1] + phd_mi_noso_nosp_nosym = [f for f in phd_mi_noso_nosp_nosym if str(f).find('lapack') == -1] -objects = {} -for k, v in sources.items(): - objects[k.replace('_src', '_obj')] = env.Object(v) - -Requires(objects['memalloc_obj'], objects['dim_mod_obj']) +sources = dim_mod + memalloc + cluster_gen + common_sub + renormalization + phd_se_noso_nosp_nosym +sources += phd_mi_noso_nosp_nosym + eig_common + eig_pw + eig_mi +# define objects +dim_mod_obj = env.Object(dim_mod) +memalloc_obj = env.Object(memalloc) +cluster_gen_obj = env.Object(cluster_gen) +common_sub_obj = env.Object(common_sub) +renormalization_obj = env.Object(renormalization) +phd_se_noso_nosp_nosym_obj = env.Object(phd_se_noso_nosp_nosym) +phd_mi_noso_nosp_nosym_obj = env.Object(phd_mi_noso_nosp_nosym) +eig_common_obj = env.Object(eig_common) +eig_pw_obj = env.Object(eig_pw) +eig_mi_obj = env.Object(eig_mi) +Requires(memalloc_obj, dim_mod_obj) -shared_objects = { - 'phd_se_noso_nosp_nosym': 'phd_se_noso_nosp_nosym/main.f', - 'phd_mi_noso_nosp_nosym': 'phd_mi_noso_nosp_nosym/main.f', - 'eig_mi' : 'eig/mi/main.f', - 'eig_pw' : 'eig/pw/main.f',} -modules = {} +# define Python extensions +common_deps = dim_mod_obj + memalloc_obj + cluster_gen_obj + common_sub_obj +deps = common_deps + renormalization_obj + phd_se_noso_nosp_nosym_obj +phd_se_mod = env.F2PY('_phd_se_noso_nosp_nosym', ['phd_se_noso_nosp_nosym/main.f'] + deps) +Requires(phd_se_mod, deps) +env.Alias('phd_se', phd_se_mod) -for k, v in shared_objects.items(): - cmd = "f2py3 -I. " + " ".join([str(_) for _ in objects if str(_).endswith('.o')]) + f"$F2PY_OPTS -c -m {k} $SOURCE" - cmd += "2>/dev/null 1>/dev/null" - modules[k + suffix] = env.Command(k + suffix, v, Action(cmd, '$FORTRANCOMSTR')) - Requires(modules[k + suffix], objects.values()) +deps = common_deps + renormalization_obj + phd_mi_noso_nosp_nosym_obj +phd_mi_mod = env.F2PY('_phd_mi_noso_nosp_nosym', ['phd_mi_noso_nosp_nosym/main.f'] + deps) +Requires(phd_mi_mod, deps) +env.Alias('phd_mi', phd_mi_mod) -#for k,v in env.items(): -# print(k,v) +deps = common_deps + renormalization_obj + eig_common_obj + eig_mi_obj +eig_mi_mod = env.F2PY('_eig_mi', ['eig/mi/main.f'] + deps) +Requires(eig_mi_mod, deps) +env.Alias('eig_mi', eig_mi_mod) -#exit() +deps = common_deps + renormalization_obj + eig_common_obj + eig_pw_obj +eig_pw_mod = env.F2PY('_eig_pw', ['eig/pw/main.f'] + deps) +Requires(eig_pw_mod, deps) +env.Alias('eig_pw', eig_pw_mod)