mirror of https://github.com/abinit/abinit.git
400 lines
12 KiB
Python
Executable File
400 lines
12 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
# Copyright (C) 2014-2025 ABINIT Group (Yann Pouillon)
|
|
#
|
|
# This file is part of the ABINIT software package. For license information,
|
|
# please see the COPYING file in the top-level directory of the ABINIT source
|
|
# distribution.
|
|
#
|
|
|
|
from __future__ import print_function, division, absolute_import
|
|
|
|
from time import gmtime,strftime
|
|
|
|
try:
|
|
from commands import getoutput
|
|
except ImportError:
|
|
from subprocess import getoutput
|
|
|
|
try:
|
|
from ConfigParser import ConfigParser,NoOptionError
|
|
except ImportError:
|
|
from configparser import ConfigParser,NoOptionError
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
class MyConfigParser(ConfigParser):
|
|
|
|
def optionxform(self,option):
|
|
return str(option)
|
|
|
|
# ---------------------------------------------------------------------------- #
|
|
|
|
#
|
|
# Subroutines
|
|
#
|
|
|
|
# File template
|
|
def macros_triggers(name,stamp,m4_changed,m4_init,m4_summary):
|
|
|
|
ret = """# Generated by %s on %s
|
|
|
|
#
|
|
# Display information about feature triggers status
|
|
#
|
|
|
|
#
|
|
# IMPORTANT NOTE
|
|
#
|
|
# This file has been automatically generated by the %s
|
|
# script. If you try to edit it, your changes will systematically be
|
|
# overwritten.
|
|
#
|
|
|
|
|
|
|
|
@M4_CHANGED@
|
|
|
|
|
|
|
|
@M4_INIT@
|
|
|
|
|
|
|
|
@M4_SUMMARY@
|
|
""" % (name,stamp,name)
|
|
|
|
ret = re.sub("@M4_CHANGED@",m4_changed,ret)
|
|
ret = re.sub("@M4_INIT@",m4_init,ret)
|
|
ret = re.sub("@M4_SUMMARY@",m4_summary,ret)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
# Changed macro
|
|
def macro_changed(trig_params):
|
|
|
|
ret = """\
|
|
# ABI_INFO_TRIGGERS_CHANGED()
|
|
# ----------------------
|
|
#
|
|
# Initializes parameters and command-line options related to feature triggers.
|
|
#
|
|
AC_DEFUN([ABI_INFO_TRIGGERS_CHANGED],[
|
|
@CHANGES@
|
|
]) # ABI_INFO_TRIGGERS_CHANGED"""
|
|
|
|
trig_chgs = ""
|
|
trig_list = sorted(trig_params.keys())
|
|
|
|
for pkg in trig_list:
|
|
|
|
opt_name = re.sub("_","-",pkg)
|
|
if ( trig_params[pkg]["status"] == "new" ):
|
|
trig_chgs += " AC_MSG_NOTICE([ * new feature trigger for %s available])\n" % pkg
|
|
trig_chgs += " AC_MSG_NOTICE([ >>> --with-%s, %s_*FLAGS])\n" % (opt_name,pkg.upper())
|
|
if ( "default_flavor" in trig_params[pkg] ):
|
|
trig_chgs += " AC_MSG_NOTICE([ >>> --with-%s-flavor (default: %s)])\n" % (pkg,trig_params[pkg]["default_flavor"])
|
|
elif ( trig_params[pkg]["status"] == "removed" ):
|
|
trig_chgs += " AC_MSG_NOTICE([ * removed feature trigger for %s])\n" % pkg
|
|
|
|
if ( trig_chgs == "" ):
|
|
trig_chgs = """\
|
|
AC_MSG_NOTICE([])
|
|
AC_MSG_NOTICE([no change in feature triggers to report])"""
|
|
else:
|
|
trig_chgs = """\
|
|
AC_MSG_NOTICE([])
|
|
AC_MSG_NOTICE([reporting changes in feature triggers:])
|
|
AC_MSG_NOTICE([])\n""" + trig_chgs
|
|
|
|
ret = re.sub("@CHANGES@",trig_chgs,ret)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
# Init macro
|
|
def macro_init(trig_params):
|
|
|
|
ret = """\
|
|
# ABI_TRIGGERS_INIT()
|
|
# -------------------
|
|
#
|
|
# Initializes parameters and command-line options related to feature triggers.
|
|
#
|
|
AC_DEFUN([ABI_TRIGGERS_INIT],[
|
|
@DEFINITIONS@
|
|
]) # ABI_TRIGGERS_INIT"""
|
|
|
|
trig_template = """\
|
|
# Init default parameters for @package@
|
|
abi_@package@_enable="@default@"
|
|
abi_@package@_init="def"
|
|
abi_@package@_prefix=""
|
|
|
|
# Command-line options for @package@
|
|
AC_ARG_WITH([@package@],
|
|
AS_HELP_STRING([--with-@package@],
|
|
[Install prefix to look for @package@, or automatic configuration if set to 'yes' or 'no' (default: @default@)]),
|
|
[ if test "${withval}" = "no" -o "${withval}" = "yes"; then
|
|
abi_@package@_enable="${withval}"
|
|
abi_@package@_init="yon"
|
|
abi_@package@_prefix=""
|
|
else
|
|
abi_@package@_enable="yes"
|
|
abi_@package@_init="dir"
|
|
abi_@package@_cppflags="@includes@"
|
|
abi_@package@_libs="@libraries@"
|
|
abi_@package@_prefix="${withval}"
|
|
fi])@with_flavor@
|
|
AC_ARG_VAR([@PACKAGE@_CPPFLAGS],
|
|
[C preprocessing flags for @package@ (default: empty)])
|
|
AC_ARG_VAR([@PACKAGE@_FCFLAGS],
|
|
[Fortran flags for @package@ (default: empty)])
|
|
AC_ARG_VAR([@PACKAGE@_LIBS],
|
|
[Library flags for @package@ (default: empty)])
|
|
|
|
if test "${@PACKAGE@_FCFLAGS}${@PACKAGE@_LIBS}" != ""; then
|
|
abi_@package@_enable="yes"
|
|
abi_@package@_init="env"
|
|
fi
|
|
|
|
# Set up trigger-related variables for @package@
|
|
abi_@package@_ok="unknown"
|
|
if test "${abi_fbk_enable}" = "yes"; then
|
|
abi_fbk_@package@_ok="@fbk_status@"
|
|
else
|
|
abi_fbk_@package@_ok="@nofbk_status@"
|
|
fi@test_flavor@
|
|
|
|
# Substitute trigger-related variables for @package@
|
|
AC_SUBST(abi_@package@_enable)@subst_flavor@
|
|
AC_SUBST(abi_@package@_init)
|
|
AC_SUBST(abi_@package@_ok)
|
|
AC_SUBST(abi_@package@_cppflags)
|
|
AC_SUBST(abi_@package@_fcflags)
|
|
AC_SUBST(abi_@package@_ldflags)
|
|
AC_SUBST(abi_@package@_libs)
|
|
AC_SUBST(abi_@package@_prefix)
|
|
AC_SUBST(abi_fbk_@package@_ok)"""
|
|
|
|
trig_sd_template = """\
|
|
# Set up trigger-related variables for @package@
|
|
if test "${abi_fbk_enable}" = "yes"; then
|
|
abi_fbk_@package@_ok="@fbk_status@"
|
|
else
|
|
abi_fbk_@package@_ok="@nofbk_status@"
|
|
fi
|
|
|
|
# Substitute trigger-related variables for @package@
|
|
AC_SUBST(abi_fbk_@package@_ok)"""
|
|
|
|
trig_defs = ""
|
|
trig_list = sorted(trig_params.keys())
|
|
|
|
for pkg in trig_list:
|
|
|
|
trig_substs= {
|
|
"PACKAGE":pkg.upper(),
|
|
"package":pkg,
|
|
"name":trig_params[pkg]["name"],
|
|
}
|
|
if ( trig_params[pkg]["fallback"] == "yes" ):
|
|
trig_substs["fbk_status"] = "avail"
|
|
trig_substs["nofbk_status"] = "disabled"
|
|
else:
|
|
trig_substs["fbk_status"] = "no"
|
|
trig_substs["nofbk_status"] = "no"
|
|
if ( trig_params[pkg]["optional"] == "yes" ):
|
|
trig_substs["default"] = "no"
|
|
else:
|
|
trig_substs["default"] = "yes"
|
|
if ( "headers" in trig_params[pkg] or \
|
|
"modules" in trig_params[pkg] ):
|
|
trig_substs["includes"] = "-I${withval}/include"
|
|
else:
|
|
trig_substs["includes"] = ""
|
|
if ( "libraries" in trig_params[pkg] ):
|
|
trig_substs["libraries"] = \
|
|
"-L${withval}/lib -l" + " -l".join(trig_params[pkg]["libraries"])
|
|
else:
|
|
trig_substs["libraries"] = ""
|
|
if ( "flavors" in trig_params[pkg] ):
|
|
flavors_list = [re.sub("^[+a-z0-9_]*:","",item) \
|
|
for item in trig_params[pkg]["flavors"]]
|
|
trig_substs["flavors"] = " ".join(flavors_list)
|
|
trig_substs["default_flavor"] = trig_params[pkg]["flavors"][0]
|
|
trig_substs["with_flavor"] = """
|
|
AC_ARG_WITH([@package@-flavor],
|
|
AS_HELP_STRING([--with-@package@-flavor],
|
|
[Flavor of @name@ to use (default: @default_flavor@),
|
|
see ~abinit/doc/build/config-template.ac9 for details]),
|
|
[abi_@package@_flavor="${withval}"],
|
|
[abi_@package@_flavor="@default_flavor@"])"""
|
|
trig_substs["subst_flavor"] = "\n AC_SUBST(abi_@package@_flavor)"
|
|
trig_substs["test_flavor"] = """
|
|
|
|
# Check that a permitted flavor value has been specified
|
|
if test "${abi_@package@_enable}" = "yes"; then
|
|
flavor_values=`echo "${abi_@package@_flavor}" | sed -e 's/+/ /g'`
|
|
tmp_flavor_ok="no"
|
|
AC_MSG_CHECKING([whether the '${abi_@package@_flavor}' @name@ flavor is valid])
|
|
for chk_flavor in @flavors@; do
|
|
for set_flavor in ${flavor_values}; do
|
|
if test "${set_flavor}" = "${chk_flavor}"; then
|
|
tmp_flavor_ok="yes"
|
|
break
|
|
fi
|
|
done
|
|
test "${tmp_flavor_ok}" = "yes" && break
|
|
done
|
|
AC_MSG_RESULT([${tmp_flavor_ok}])
|
|
if test "${tmp_flavor_ok}" = "no"; then
|
|
AC_MSG_ERROR([invalid @name@ flavor: '${abi_@package@_flavor}'])
|
|
fi
|
|
else
|
|
abi_@package@_flavor="none"
|
|
fi"""
|
|
else:
|
|
trig_substs["flavors"] = ""
|
|
trig_substs["default_flavor"] = ""
|
|
trig_substs["with_flavor"] = ""
|
|
trig_substs["subst_flavor"] = ""
|
|
trig_substs["test_flavor"] = ""
|
|
|
|
# Make 2 passes of substitutions, since some substitutions contain
|
|
# patterns themselves
|
|
if ( trig_params[pkg]["detector"] == "steredeg" ):
|
|
new_def = trig_sd_template
|
|
else:
|
|
new_def = trig_template
|
|
for subst in trig_substs:
|
|
new_def = re.sub("@%s@" % subst,trig_substs[subst],new_def)
|
|
for subst in trig_substs:
|
|
new_def = re.sub("@%s@" % subst,trig_substs[subst],new_def)
|
|
if ( trig_defs != "" ):
|
|
trig_defs += "\n\n"
|
|
trig_defs += new_def
|
|
|
|
ret = re.sub("@DEFINITIONS@",trig_defs,ret)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
# Summary macro
|
|
def macro_summary(trig_params):
|
|
|
|
ret = """\
|
|
# ABI_TRIGGERS_SUMMARY()
|
|
# ----------------------
|
|
#
|
|
# Reports about the current feature triggers status.
|
|
#
|
|
AC_DEFUN([ABI_TRIGGERS_SUMMARY],[
|
|
@TRIG_FORMAT@
|
|
# Display configuration
|
|
cat <<EOF
|
|
|
|
Abinit feature triggers status
|
|
==============================
|
|
|
|
The following summary table indicates the status of the feature triggers,
|
|
whether they are available and working, how they have been initialized
|
|
and whether there are fallbacks to substitute broken ones.
|
|
|
|
@TRIG_STATUS@
|
|
|
|
EOF
|
|
]) # ABI_TRIGGERS_SUMMARY"""
|
|
|
|
# Report status of each package
|
|
trig_form = ""
|
|
trig_stat = " +----------------+--------+--------+--------+--------+\n"
|
|
trig_stat += " |Feature |Enabled |Init |Working |Fallback|\n"
|
|
trig_stat += " +----------------+--------+--------+--------+--------+\n"
|
|
for pkg in sorted(trig_params.keys()):
|
|
if ( trig_params[pkg]["detector"] == "steredeg" ):
|
|
pfx = "sd"
|
|
else:
|
|
pfx = "abi"
|
|
trig_form += " tmp_e_%s=`echo \"${%s_%s_enable}\" | awk '{printf(\"%%-8s\",[$]1);}'`\n" % (pkg,pfx,pkg)
|
|
trig_form += " tmp_i_%s=`echo \"${%s_%s_init}\" | awk '{printf(\"%%-8s\",[$]1);}'`\n" % (pkg,pfx,pkg)
|
|
trig_form += " tmp_w_%s=`echo \"${%s_%s_ok}\" | awk '{printf(\"%%-8s\",[$]1);}'`\n" % (pkg,pfx,pkg)
|
|
trig_form += " tmp_f_%s=`echo \"${abi_fbk_%s_ok}\" | awk '{printf(\"%%-8s\",[$]1);}'`\n" % (pkg,pkg)
|
|
trig_stat += " |%-16s|${tmp_e_%s}|${tmp_i_%s}|${tmp_w_%s}|${tmp_f_%s}|\n" % \
|
|
(pkg,pkg,pkg,pkg,pkg)
|
|
trig_stat += " +----------------+--------+--------+--------+--------+"
|
|
|
|
# Substitute macro
|
|
ret = re.sub("@TRIG_FORMAT@",trig_form,ret)
|
|
ret = re.sub("@TRIG_STATUS@",trig_stat,ret)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------------- #
|
|
|
|
#
|
|
# Main program
|
|
#
|
|
|
|
# Initial setup
|
|
my_name = "make-macros-triggers"
|
|
my_configs = ["config/specs/dependencies.conf"]
|
|
my_output = "config/m4/auto-triggers.m4"
|
|
|
|
# Check if we are in the top of the ABINIT source tree
|
|
if ( not os.path.exists("configure.ac") or
|
|
not os.path.exists("src/98_main/abinit.F90") ):
|
|
print("%s: You must be in the top of an ABINIT source tree." % my_name)
|
|
print("%s: Aborting now." % my_name)
|
|
sys.exit(1)
|
|
|
|
# Read config file(s)
|
|
for cnf_file in my_configs:
|
|
if ( os.path.exists(cnf_file) ):
|
|
if ( re.search(r"\.cf$",cnf_file) ):
|
|
execfile(cnf_file)
|
|
else:
|
|
print("%s: Could not find config file (%s)." % (my_name,cnf_file))
|
|
print("%s: Aborting now." % my_name)
|
|
sys.exit(2)
|
|
|
|
# What time is it?
|
|
now = strftime("%Y/%m/%d %H:%M:%S +0000",gmtime())
|
|
|
|
# Init
|
|
cnf = MyConfigParser()
|
|
cnf.read(my_configs[0])
|
|
abinit_triggers = []
|
|
abinit_fallbacks = []
|
|
triggers_params = {}
|
|
for pkg in cnf.sections():
|
|
triggers_params[pkg] = {}
|
|
triggers_params[pkg]["compounds"] = cnf.get(pkg,"compounds").split()
|
|
triggers_params[pkg]["detector"] = cnf.get(pkg,"detector")
|
|
triggers_params[pkg]["fallback"] = cnf.get(pkg,"fallback")
|
|
triggers_params[pkg]["name"] = cnf.get(pkg,"name")
|
|
triggers_params[pkg]["optional"] = cnf.get(pkg,"optional")
|
|
triggers_params[pkg]["status"] = cnf.get(pkg,"status")
|
|
abinit_triggers.append(pkg)
|
|
if ( cnf.get(pkg,"fallback") == "yes" ):
|
|
abinit_fallbacks.append(pkg)
|
|
if ( cnf.has_option(pkg,"flavors") ):
|
|
triggers_params[pkg]["flavors"] = cnf.get(pkg,"flavors").split()
|
|
abinit_triggers.sort()
|
|
abinit_fallbacks.sort()
|
|
|
|
# Write down macro
|
|
m4_changed = macro_changed(triggers_params)
|
|
m4_init = macro_init(triggers_params)
|
|
m4_summary = macro_summary(triggers_params)
|
|
with open(my_output, "w") as m4_file:
|
|
m4_file.write(macros_triggers(my_name,now,m4_changed,m4_init,m4_summary))
|